슬기로운 해커 생활

C언어

[C언어] 코드업 기초 100제 풀면서 느낀점

Tjdmin1 2023. 1. 28. 02:41

C언어로 코드업 기초 100제를 푼 인증사진입니다.

C언어로 코드업 기초 100제를 푼 인증사진

기초부터 이차원배열까지 다시 공부해 볼수있는 좋은 기회였습니다.

특히 배열을 만지기 어려워했는데 코드업 기초 100제를 풀면서 배열에 대한 이해도와 배열을 이용한 코드짜기 실력이 늘었습니다.

"배열을 잘 못다루겠다!" 혹은 "배열에 대한 이해가 부족하다!" 이런분들에겐 코드업 기초 100제를 추천드리고 싶네요!

 

코드업에선 자잘자잘한 TMI를 잘 알려줘서 지식도 얻었습니다.

예를들면 1085번에 소리파일 저장방식이나 그림파일 저장 방식등등..

(사실 그림파일은 정보시간에 배웠었는데 까먹었었음 ㅎㅎ..)

 

1001번부터 1084번까진 막힘없이 풀어나가다 1085번부턴 살짝 난이도가 있어졌습니다.

그래도 기초라 그런지 충분히 할 수 있더라고요 :)

1099번과 1098번은 마지막 문제라 제일 어려울줄 알았는데 의외로 생각했던 것보단 쉬웠습니다.

그래도 코드업 기초 100제 문제중 어려웠던 3문제는 1097 / 1098 / 1099 였습니다

제가 푼 소스코드를 공개하자면

 

1097 - [기초-2차원배열] 바둑알 십자 뒤집기

[1097번 문제 바로가기]

#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차원배열] 설탕과자 뽑기

[1098번 문제 바로가기]

#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차원배열] 성실한 개미

[1099번 문제 바로가기]

 

#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번을 통해 재귀함수와 포인터 그리고 동적할당에 대해 다시 공부를 해 개념 이해를 도와준거 같았습니다 :)

 

다음엔 파이썬으로 작성하겠습니다 :)

좋은 하루 되세요 모두!