상세 컨텐츠

본문 제목

[CodeUp] C언어 기초 100제 풀이 (1097번 ~ 1099번)

C언어

by idea8590 2026. 2. 5. 06:08

본문

반응형

CodeUp 기초 100제: 2차원 배열 완전 정복 (1097 ~ 1099)

이 구간은 프로그래밍 기초의 꽃이라 불리는 2차원 배열시뮬레이션을 다룹니다. 격자판 위에서 데이터를 조작하고, 물체를 이동시키는 로직을 구현하며 알고리즘적 사고력을 완성하는 단계입니다.

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

문제 설명

바둑판(19 * 19)에 흰 돌(1) 또는 검은 돌(0)이 모두 꽉 채워져 놓여있다. n개의 좌표를 입력받아 그 좌표에 있는 돌을 중심으로 가로 줄과 세로 줄의 색을 모두 뒤집는 프로그램을 작성해보자.

  • 뒤집는다는 것은 1을 0으로, 0을 1로 바꾼다는 뜻이다.
  • 입력되는 좌표(x, y)를 기준으로 x행 전체와 y열 전체의 색을 반전시켜야 한다.

입력

  1. 첫 줄부터 19줄에 걸쳐 현재 바둑판의 상태(0 또는 1)가 공백을 두고 입력된다.
  2. 20번째 줄에 십자 뒤집기 횟수(n)가 입력된다.
  3. 그 다음 줄부터 n개의 좌표(x, y)가 입력된다. (좌표는 1부터 19까지이다.)

출력

십자 뒤집기 결과를 출력한다. (각 줄의 숫자는 공백으로 구분)

소스 코드

#include <stdio.h>

int main() {
    int board[20][20]; // 1~19 인덱스를 사용하기 위해 20x20 선언
    int n, i, j, x, y;

    // 1. 현재 바둑판 상태 입력 받기 (19x19)
    for(i = 1; i <= 19; i++) {
        for(j = 1; j <= 19; j++) {
            scanf("%d", &board[i][j]);
        }
    }

    // 2. 뒤집기 횟수 입력
    scanf("%d", &n);

    // 3. 횟수만큼 좌표를 입력받아 뒤집기 실행
    for(i = 1; i <= n; i++) {
        scanf("%d %d", &x, &y);
        
        // 십자 뒤집기 로직
        for(j = 1; j <= 19; j++) {
            // 가로 줄(x행) 뒤집기: 0이면 1, 1이면 0
            if(board[x][j] == 0) board[x][j] = 1;
            else board[x][j] = 0;

            // 세로 줄(y열) 뒤집기: 0이면 1, 1이면 0
            if(board[j][y] == 0) board[j][y] = 1;
            else board[j][y] = 0;
        }
    }

    // 4. 최종 결과 출력
    for(i = 1; i <= 19; i++) {
        for(j = 1; j <= 19; j++) {
            printf("%d ", board[i][j]);
        }
        printf("\n");
    }

    return 0;
}

입력 예시

(복사하여 테스트하세요. 19줄의 바둑판 상태, 횟수 1, 좌표 10 10 입니다.)

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1
10 10

출력 예시

(10행과 10열이 뒤집힌 상태)

0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 

문제 해설

  1. 토글(Toggle): 값을 반전시키는 것을 말합니다. if(val==0) val=1; else val=0; 구문을 사용해 구현합니다.
  2. 행과 열의 순회: 입력받은 좌표 (x, y)에 대해, board[x][j]를 반복하면 가로줄 전체를, board[j][y]를 반복하면 세로줄 전체를 접근할 수 있습니다.
  3. 중복 처리: 이 알고리즘대로라면 중심점 (x, y)는 가로 검사 때 한 번, 세로 검사 때 한 번, 총 두 번 뒤집히게 되어 원래 색상으로 돌아옵니다. 문제 의도상 이는 정상적인 동작입니다.

1098 : [기초-2차원배열] 설탕과자 뽑기

문제 설명

부모님과 함께 놀러간 영일이는 설탕과자(설탕을 녹여 물고기 등의 모양을 만든 것) 뽑기를 보게 되었다. 길이가 다른 막대 여러 개를 격자판에 놓는데, 격자판의 세로(h), 가로(w), 막대의 개수(n), 각 막대의 길이(l), 방향(d), 좌표(x, y)를 입력받아 막대를 놓는 프로그램을 작성해 보자.

  • 막대가 놓인 곳은 1, 없는 곳은 0으로 채운다.
  • 방향(d): 0은 가로 방향, 1은 세로 방향이다.

입력

  1. 첫 줄에 격자판의 세로(h), 가로(w)가 공백을 두고 입력된다. (1 <= h, w <= 100)
  2. 두 번째 줄에 놓을 막대의 개수(n)가 입력된다. (1 <= n <= 10)
  3. 세 번째 줄부터 각 막대의 길이(l), 방향(d), 좌표(x, y)가 n줄 입력된다.

출력

막대가 놓인 후의 격자판의 상태를 출력한다.

소스 코드

#include <stdio.h>

int main() {
    int h, w, n, l, d, x, y;
    int board[101][101] = {0}; // 격자판 최대 크기가 100이므로 101로 넉넉히 초기화
    int i, j;

    // 1. 격자판 크기 및 막대 개수 입력
    scanf("%d %d", &h, &w);
    scanf("%d", &n);

    // 2. 막대 정보 입력 및 배치
    for(i = 1; i <= n; i++) {
        scanf("%d %d %d %d", &l, &d, &x, &y);

        for(j = 0; j < l; j++) { // 막대 길이(l)만큼 반복
            if(d == 0) { 
                // 가로 방향(d=0): 행(x)은 고정, 열(y)이 증가
                board[x][y + j] = 1;
            }
            else { 
                // 세로 방향(d=1): 열(y)은 고정, 행(x)이 증가
                board[x + j][y] = 1;
            }
        }
    }

    // 3. 결과 출력
    for(i = 1; i <= h; i++) {
        for(j = 1; j <= w; j++) {
            printf("%d ", board[i][j]);
        }
        printf("\n");
    }

    return 0;
}

입력 예시

5 5
3
2 0 1 1
3 1 2 3
4 1 2 5

출력 예시

1 1 0 0 0 
0 0 1 0 1 
0 0 1 0 1 
0 0 1 0 1 
0 0 0 0 1 

문제 해설

  1. 방향에 따른 좌표 변화:
    • 가로(d=0): 오른쪽으로 길어지므로 열 번호(y)가 1씩 증가합니다. -> board[x][y+j] = 1
    • 세로(d=1): 아래쪽으로 길어지므로 행 번호(x)가 1씩 증가합니다. -> board[x+j][y] = 1
  2. 반복문 범위: 길이를 l이라고 할 때, j를 0부터 l-1까지 반복시켜 시작점부터 끝점까지 정확하게 채웁니다.

1099 : [기초-2차원배열] 성실한 개미

문제 설명

개미는 오른쪽(→) 또는 아래쪽(↓)으로만 움직일 수 있다. 미로 상자(10 * 10)에 개미(좌표 2, 2에서 시작)가 이동한 경로를 9로 표시하여 출력해보자.

  • 0: 갈 수 있는 곳
  • 1: 벽 또는 장애물
  • 2: 먹이 (먹이에 도착하면 멈춘다)
  • 개미는 오른쪽으로 갈 수 있다면 오른쪽으로 먼저 가고, 오른쪽에 벽이 있으면 아래쪽으로 간다.
  • 먹이를 찾거나, 더 이상 움직일 수 없으면 이동을 멈춘다.

입력

10 * 10 크기의 미로 상자 구조가 입력된다.

출력

개미가 이동한 경로를 9로 표시해 출력한다.

소스 코드

#include <stdio.h>

int main() {
    int map[11][11]; // 10x10 미로
    int i, j;
    int x = 2, y = 2; // 개미의 시작 좌표는 (2, 2)로 고정됨

    // 1. 미로 정보 입력
    for(i = 1; i <= 10; i++) {
        for(j = 1; j <= 10; j++) {
            scanf("%d", &map[i][j]);
        }
    }

    // 2. 개미 이동 시뮬레이션 (무한 루프)
    while(1) {
        // 경우 1: 현재 위치가 먹이(2)인 경우
        if(map[x][y] == 2) { 
            map[x][y] = 9;   // 먹은 자리를 표시하고
            break;           // 종료
        }

        map[x][y] = 9; // 현재 위치를 9(방문함)로 변경

        // 경우 2: 오른쪽 이동 가능 여부 확인
        if(map[x][y + 1] != 1) { // 오른쪽이 벽(1)이 아니라면 (0이거나 2)
            y++; // 오른쪽으로 한 칸 이동 (열 증가)
        }
        // 경우 3: 오른쪽은 막혔고, 아래쪽 이동 가능 여부 확인
        else if(map[x + 1][y] != 1) { // 아래쪽이 벽(1)이 아니라면
            x++; // 아래쪽으로 한 칸 이동 (행 증가)
        }
        // 경우 4: 오른쪽, 아래쪽 모두 막힌 경우
        else {
            break; // 더 이상 갈 곳이 없으므로 종료
        }
    }

    // 3. 최종 미로 상태 출력
    for(i = 1; i <= 10; i++) {
        for(j = 1; j <= 10; j++) {
            printf("%d ", map[i][j]);
        }
        printf("\n");
    }

    return 0;
}

입력 예시

1 1 1 1 1 1 1 1 1 1
1 0 0 1 0 0 0 0 0 1
1 0 0 1 1 1 0 0 1 1
1 0 0 0 0 0 0 1 0 1
1 0 0 0 0 0 0 1 0 1
1 0 0 0 0 1 0 1 0 1
1 0 0 0 0 1 2 1 0 1
1 0 0 0 0 1 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1

출력 예시

1 1 1 1 1 1 1 1 1 1 
1 9 9 1 0 0 0 0 0 1 
1 0 9 1 1 1 0 0 1 1 
1 0 9 9 9 9 9 1 0 1 
1 0 0 0 0 0 9 1 0 1 
1 0 0 0 0 1 9 1 0 1 
1 0 0 0 0 1 9 1 0 1 
1 0 0 0 0 1 0 0 0 1 
1 0 0 0 0 0 0 0 0 1 
1 1 1 1 1 1 1 1 1 1 

문제 해설

  1. 우선순위 로직: 문제의 핵심은 "오른쪽을 먼저 본다"는 것입니다. if문으로 오른쪽(y+1)을 먼저 검사하고, 그것이 불가능할 때 else if로 아래쪽(x+1)을 검사해야 합니다.
  2. 종료 조건의 위치: 먹이(2)를 만났을 때 바로 종료하는 것이 아니라, 해당 위치를 9로 표시한 직후에 종료해야 합니다.
  3. 좌표 관리: 개미의 위치를 나타내는 변수 x, y를 계속 갱신하면서 2차원 배열을 탐색하는 전형적인 시뮬레이션 문제입니다.

결론 요약 (CodeUp 기초 100제 완주)

  1. 완전 정복: 1097~1099번은 2차원 배열의 인덱스 조작, 좌표 이동, 조건에 따른 시뮬레이션을 모두 포함하는 종합 문제입니다.
  2. 좌표계 이해: 행(x)과 열(y)의 개념, 그리고 방향(가로/세로)에 따라 어떤 인덱스가 변하는지를 정확히 이해해야 합니다.
  3. 로직 구현력: "오른쪽 우선, 안 되면 아래"와 같은 말로 된 규칙을 if-else 코드로 정확히 옮기는 능력이 길러졌습니다.
  4. 기초 완성: 여기까지 스스로 풀 수 있다면 C언어의 문법(변수, 조건문, 반복문, 배열) 활용 능력은 충분히 갖춰졌습니다.
  5. 다음 단계: 이제 자료구조(스택, 큐)나 더 복잡한 알고리즘(탐색, 정렬)을 학습하며 실력을 확장해 나갈 차례입니다. 고생하셨습니다!
반응형

관련글 더보기