C언어로 코드업 기초 100제를 푼 인증사진입니다.
기초부터 이차원배열까지 다시 공부해 볼수있는 좋은 기회였습니다.
특히 배열을 만지기 어려워했는데 코드업 기초 100제를 풀면서 배열에 대한 이해도와 배열을 이용한 코드짜기 실력이 늘었습니다.
"배열을 잘 못다루겠다!" 혹은 "배열에 대한 이해가 부족하다!" 이런분들에겐 코드업 기초 100제를 추천드리고 싶네요!
코드업에선 자잘자잘한 TMI를 잘 알려줘서 지식도 얻었습니다.
예를들면 1085번에 소리파일 저장방식이나 그림파일 저장 방식등등..
(사실 그림파일은 정보시간에 배웠었는데 까먹었었음 ㅎㅎ..)
1001번부터 1084번까진 막힘없이 풀어나가다 1085번부턴 살짝 난이도가 있어졌습니다.
그래도 기초라 그런지 충분히 할 수 있더라고요 :)
1099번과 1098번은 마지막 문제라 제일 어려울줄 알았는데 의외로 생각했던 것보단 쉬웠습니다.
그래도 코드업 기초 100제 문제중 어려웠던 3문제는 1097 / 1098 / 1099 였습니다
제가 푼 소스코드를 공개하자면
1097 - [기초-2차원배열] 바둑알 십자 뒤집기
#include <stdio.h>
int main(void){
int arr[20][20] = { 0, }; // 20 * 20 배열 만들고 초기화
for(int i=0; i<19; i++){ // 이중 for문으로 값을 입력받기
for(int j=0; j<19; j++){
scanf("%d", &arr[i][j]);
}
}
int n, x, y; // n은 실행횟수 x, y는 바꿀 좌표
scanf("%d", &n);
for(int i=0; i<n; i++){ // n만큼 반복
scanf("%d %d", &x, &y); // 좌표 입력
for(int k = 0; k<19; k++){ // 가로줄 바꾸기
if(arr[x-1][k] == 0){ // 0일 경우 1로
arr[x-1][k] = 1;
}else{ // 1일 경우 0으로
arr[x-1][k] = 0;
}
}
for(int k = 0; k<19; k++){ // 세로줄 바꾸기
if(arr[k][y-1] == 0){ // 0일경우 1로
arr[k][y-1] = 1;
}else{ // 1일경우 0으로
arr[k][y-1] = 0;
}
}
}
for(int i=0; i<19; i++){ // 이중 for문으로 배열 출력하기
for(int j=0; j<19; j++){
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
1098 - [기초-2차원배열] 설탕과자 뽑기
#include <stdio.h>
#include <stdlib.h>
int main(void){
int h, w, n, l, d, x, y; //변수생성
scanf("%d %d", &h, &w); // 배열의 세로와 가로를 입력받음
int** arr = NULL; // 이중 포인터 생성
arr = (int**)malloc(sizeof(int*) * h); // arr에 8바이트 * 높이 만큼 포인터 배열 생성
for(int i = 0; i < h; i++){ // for 문을 이용해 index i번에 또 4 * 가로 만큼 이차원 배열을 만들고
arr[i] = (int*)malloc(sizeof(int) * w);
for (int j = 0; j < w; j++){ // 이중 for문을 이용해 포인터 이차원 배열의 값을 0으로 모두 초기화
arr[i][j] = 0;
}
}
scanf("%d", &n); //막대 개수 입력받기
for(int i = 0; i < n; i++){ //막대 개수만큼 반복하기
scanf("%d %d %d %d", &l, &d, &x, &y); //길이,방향,좌표값 입력받기
x = x - 1; //index는 0부터 시작이니까 -1씩 해줌
y = y - 1;
l = l - 1;
if(d == 0){ // 가로방향일때
arr[x][y] = 1; //좌표값부터 가로방향으로 막대기를 놓으니까 좌표값을 1로바꿈
y++; //가로니까 y++해줌
for(int i = 0; i < l; i++){ //길이만큼 기로로 1로 바꿔줌
arr[x][y] = 1;
y++;
}
}else{ // 세로방향일떄
arr[x][y] = 1; //좌표값부터 세로방향으로 막대기를 놓으니까 좌표값을 1로바꿈
x++; //세로니까 x++해줌
for(int i = 0; i < l; i++){ //길이만큼 세로로 1로 바꿔줌
arr[x][y] = 1;
x++;
}
}
}
for(int i = 0; i < h; i++){ //이중 for문을 이용하여 포인터 이차원 배열 출력
for(int j = 0; j < w; j++){
printf("%d ", arr[i][j]);
}
printf("\n");
}
for (int i = 0; i < h; i++){//동적할당 해제 해줌
free(arr[i]);
}
free(arr);
return 0;
}
1099 - [기초-2차원배열] 성실한 개미
#include <stdio.h>
void ant(int a[][10], int x, int y); //재귀함수 이용
int main(void){
int x, y; //개미의 좌표값 선언후 초기화
x = 1;
y = 1;
int map[10][10] = { 0, }; //이차원 배열을 만들고 리셋
for(int i = 0; i < 10; i++){ //이중 for문을 통해 장애물을 입력
for (int j = 0; j < 10; j ++){
scanf("%d", &map[i][j]);
}
}
ant(map, x, y); //함수로 넘어감(CALL)
for(int i = 0; i < 10; i++){ //이차원 배열 출력
for (int j = 0; j < 10; j ++){
printf("%d ", map[i][j]);
}
printf("\n");
}
return 0;
}
void ant(int map[][10], int x, int y){ //이차원 배열과 좌표를 넘김
if(map[x][y] == 2){ //서있는곳이 2(먹이)라면
map[x][y] = 9; //9(지나간길)로 바꾸고 리턴
return;
}else{
map[x][y] =9; //개미가 서있는곳을 9로 바꿈
if(map[x][y+1] == 0){ //서있는곳 오른쪽에 0(장애물 없을경우)
++y; //++y후
map[x][y] = 9; //개미가 지나간 길로 바꿔줌
fucking_ant(map, x, y); //함수안에 함수를 또 호출(재귀함수)
}else if(map[x][y+1] == 1){ //개미가 서있는곳 가로로 오른쪽에 1(장애물 있을경우)
if(map[x+1][y] == 2){ //세로에서 아래로 가는곳에 먹이가있다면
++x; //++x후
map[x][y] = 9; //9(지나온 길)로 바꿔서 리턴
return;
}else if(map[x+1][y] == 1){ //1(막혔을 경우) 못가리까 그냥 리턴
return;
}else if(map[x+1][y] == 0){ //0(안막혔을 경우)
++x; //++x후
map[x][y] = 9; //9(지나온 길)로 바꾸고
fucking_ant(map, x, y); //함수안에 함수를 또 호출(재귀함수)
}
}else if(map[x][y+1] == 2){ //세로 오른쪽에 바로 먹이가 있을 경우
++y; //++y후
map[x][y] = 9; //9(지나온 길)로 바꿔서 리턴
return;
}
}
}
재귀함수를 사용한 버전이고 아래에 for문을 사용한 버전을 주석없이 적어드릴게요!
원리는 비슷해서 주석 안쓸게요!
#include <stdio.h>
int main(void){
int x, y, vatual_y;
x = 1;
y = 1;
int map[10][10] = { 0, };
for(int i = 0; i < 10; i++){
for (int j = 0; j < 10; j ++){
scanf("%d", &map[i][j]);
}
}
if(map[x][y] == 2){
map[x][y] = 9;
}else{
map[x][y] = 9;
while (1)
{
if(map[x][y+1] == 0){
++y;
map[x][y] = 9;
}else if(map[x][y+1] == 1){
if(map[x+1][y] == 2){
++x;
map[x][y] = 9;
break;
}else if(map[x+1][y] == 1){
break;
}else if(map[x+1][y] == 0){
++x;
map[x][y] = 9;
}
}else if(map[x][y+1] == 2){
++y;
map[x][y] = 9;
break;
}
}
}
for(int i = 0; i < 10; i++){
for (int j = 0; j < 10; j ++){
printf("%d ", map[i][j]);
}
printf("\n");
}
return 0;
}
이렇게 저는 풀었어요!
나중에 보니까 98번 포인터 배열을 안쓰고 그냥 인덱스 100으로 넣고 풀면 된다는걸 알았지만...
그래도 포인터와 동적할당까지 공부하여 많이 도움이 됬어요!
전 하루종일 집중해서 풀면 이틀 안에 풀 수 있을거같아요.
이거 풀면서 제가 알고리즘 엄청 못한다는것도 알게 됬네요 ㅠㅠ :)
하여튼 풀면서 자잘자잘한 몰랐던 정보들도 알게되어서 좋은 경험을 해본거같네요 :)
특히 저는 1098번과 1099번을 통해 재귀함수와 포인터 그리고 동적할당에 대해 다시 공부를 해 개념 이해를 도와준거 같았습니다 :)
다음엔 파이썬으로 작성하겠습니다 :)
좋은 하루 되세요 모두!