[P4C 4기]/과제

[P4C 4기] 3주차 과제 - 코드업 기초 100제 (~100)

criling 2022. 5. 3. 10:51

1번 1073 : [기초-반복실행구조] 0 입력될 때까지 무한 출력하기2

입력

정수가 순서대로 입력된다.
-2147483648 ~ +2147483647, 단 개수는 알 수 없다.

 

입력 예시

7 4 2 3 0 1 5 6 9 10 8

 

출력

입력된 정수를 줄을 바꿔 하나씩 출력하는데, 0이 입력되면 종료한다.
(0은 출력하지 않는다.)

 

출력 예시

7

4

2

3

 

 

풀이

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
int main() {
    int num1;
    reload:
    scanf("%d"&num1);
    
    if (num1 != 0) {
        printf("%d\n", num1);
        goto reload;
    }
 
    return 0;
}
cs

 

위 처럼 goto문을 사용하여 reload라는 레이블로 이동하여 여러번 입력받을 수 있습니다.

변수는 하나이지만 입력버퍼에 데이터가 남아있기 때문에 해당 데이터가 공백을 기준으로 값이 변수에 들어갈 수 있었습니다.

 

goto문을 적절히 사용하지 않는 경우 "스파게티 코드"가 되어 코드가 복잡해질 수 있기 때문에 상황에 맞게 사용하는게 중요합니다.

goto문을 사용하지 않고 아래와 같이 문제를 해결할 수도 있습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
int main() {
    int num1;
 
    scanf("%d"&num1);
    while (num1 != 0) {
        printf("%d\n", num1);
        scanf("%d"&num1);
    }
 
    return 0;
}
cs

 

 

 

2번 1090 : [기초-종합] 수 나열하기2

입력

시작 값(a), 등비의 값(r), 몇 번째 인지를 나타내는 정수(n)가
공백을 두고 입력된다.(모두 0 ~ 10)

 

입력 예시

2 3 7

 

 

출력

n번째 수를 출력한다.

 

출력 예시

1458

 

풀이

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <math.h>
 
int main() {
    int a, r, n;
 
    scanf("%d %d %d"&a, &r, &n);
    printf("%d", a * pow(r, (n - 1)));
 
    return 0;
}
cs

 

pow 함수를 사용하여 등비 수열을 나타내려고 했었습니다.

하지만 위 그림과 같이 출력 값이 0으로 나와 이상하다고 생각하여 pow 함수에 대해 찾아보던 중 pow 함수의 반환 자료형이 double이라는 것을 알게 되었습니다.

 

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <math.h>
 
int main() {
    int a, r, n;
 
    scanf("%d %d %d"&a, &r, &n);
    printf("%.f", a * pow(r, (n - 1)));
 
    return 0;
}
cs

 

pow의 반환 값에 맞게 double이라는 자료형을 출력하기 위해 %f를 사용하여 출력해주어 문제를 해결할 수 있었습니다.

 

지수 연산을 통해 나온 값이 정수 자료형이 아닌 실수 자료형으로 나오는게 신기하여 아래와 같이 테스트를 해봤었습니다.

 

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <math.h?
 
int main() {
    float a = 2.5;
    
    printf("%f",pow(a, a));
 
    return 0;
}
cs

$2.5^{2.5}$의 결과로 9.882118이라는 값이 나왔습니다. 제곱하는 수가 실수(분수)인 경우도 있기 때문에 pow의 반환 자료형이 double이 된 것 같습니다.

 

3번 1091 : [기초-종합] 수 나열하기3

입력

시작 값(a), 곱할 값(m), 더할 값(d), 몇 번째 인지를 나타내는 정수(n)가
공백을 두고 입력된다.(a, m, d는 -50 ~ +50, n은 10이하의 자연수)

 

입력 예시

1- 2 1 8

 

출력

n번째 수를 출력한다.

 

출력 예시

-85

 

 

풀이

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
 
int main() {
    int a, m, d, n;
    scanf("%d %d %d %d"&a, &m, &d, &n);
 
    for (int i = 0; i < n-1; i++)
        a = a * m + d;
    printf("%d ", a);
    return 0;
}
cs

입력 예시와 출력 예시가 맞았기에 정답도 맞다고 생각하였는데 오답이 나왔었습니다.

계산되어 출력될 a 변수의 자료형이 잘못되었다고 판단되어 a의 자료형을 int에서 long long으로 바꾸어 주었습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
 
int main() {
    long long a;
    int m, d, n;
    scanf("%lld %d %d %d"&a, &m, &d, &n);
 
    for (int i = 0; i < n - 1; i++)
        a = a * m + d;
    printf("%lld ", a);
    return 0;
}
cs

 

이와 같이 변수가 계산되고 다시 저장될 때의 크기까지 고려하여 자료형을 선택해야 한다는 것을 알 수 있었습니다.

 

 

 

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

입력

바둑알이 깔려 있는 상황이 19 * 19 크기의 정수값으로 입력된다.
십자 뒤집기 횟수(n)가 입력된다.
십자 뒤집기 좌표가 횟수(n) 만큼 입력된다. 단, n은 10이하의 자연수이다.

 

입력 예시

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

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

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

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

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

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

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

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

0 0 0 0 0 0 0 0 0 1 0 1 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 1 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 1 0 0 0 0 0 0 0

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

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

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

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

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

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

2

10 10

12 12

 

출력

십자 뒤집기 결과를 출력한다.

 

출력 예시

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 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 0 1 0 0 0 0 0 0 0

0 0 0 0 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 0 1 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
 
int main() {
    int badukpan[19][19], raw, col, num;
    for (raw = 0; raw < 19; raw++)
        for (col = 0; col < 19; col++)
            scanf("%d",&badukpan[raw][col]);
 
    scanf("%d"&num);
 
    for (int i = 0; i < num; i++){
        scanf("%d %d"&raw, &col);
        for (int j = 0; j < 19; j++)
            badukpan[raw - 1][j] = badukpan[raw - 1][j] == 0 ? 1 : 0;
        for (int j = 0; j < 19; j++)
            badukpan[j][col - 1= badukpan[j][col - 1== 0 ? 1 : 0;
    }
 
 
    for (raw = 0; raw < 19; raw++) {
        for (col = 0; col < 19; col++)
            printf("%d ", badukpan[raw][col]);
        printf("\n");
    }
    return 0;
}
cs

해당 좌표가 주어졌을 때 좌표 기준 행과 열을 모두 뒤집어야 하는 문제였습니다. 

3항 연산자를 이용하여 해당 값이 가지는 반대 값(0 또는 1)을 가지도록 만들어 줄 수 있었습니다.

 

 

 

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

입력

10*10 크기의 미로 상자의 구조와 먹이의 위치가 입력된다.

 

입력 예시

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 0 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

 

출력

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

 

출력 예시

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 0 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
 
int main() {
    int ant_house[10][10], i ,j, x=2, y=2, ant;
 
    for (i = 0; i < 10; i++)
        for (j = 0; j < 10; j++)
            scanf("%d"&ant_house[i][j]);
    
    while (1) {
        if (ant_house[x - 1][y - 1!= 1) {
            ant = ant_house[x - 1][y - 1];
            ant_house[x - 1][y - 1= 9;
            if (ant == 2)
                break;
        }
 
        if (ant_house[x - 1][y] == 1)    
            x++;
        else
            y++;
    }
    for (i = 0; i < 10; i++) {
        for (j = 0; j < 10; j++)
            printf("%d ", ant_house[i][j]);
        printf("\n");
    }
    return 0;
}
cs

처음 정답을 제출하였을 때 Runtime Error:Segmentation fault 오류가 발생했었습니다.

먹이를 먹었을 때만 while문을 빠져 나오고, 먹이를 먹지 못한 경우에 대해 처리를 해주지 않아 while문이 끝나지 않았기 때문입니다.

 

그렇기에 개미가 움직이지 못하는 상황은 현재 자리에서 오른쪽과 아래쪽에 벽이 있을 경우이기 때문에 해당 조건을 추가해주어 문제를 해결할 수 있었습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
 
int main() {
    int ant_house[10][10], i ,j, x=2, y=2, ant;
 
    for (i = 0; i < 10; i++)
        for (j = 0; j < 10; j++)
            scanf("%d"&ant_house[i][j]);
    
    while (1) {
        if (ant_house[x - 1][y - 1!= 1) {
            ant = ant_house[x - 1][y - 1];
            ant_house[x - 1][y - 1= 9;
            if (ant == 2)
                break;
        }
 
        if (ant_house[x - 1][y] == 1) {
            if (ant_house[x][y - 1== 1)
                break;
            x++;
        }
        
        else
            y++;
    }
    for (i = 0; i < 10; i++) {
        for (j = 0; j < 10; j++)
            printf("%d ", ant_house[i][j]);
        printf("\n");
    }
    return 0;
}
cs

 

 

코드업 기초 100제를 마치며

기초 100제를 풀면서 C언어를 다시 공부할 수 있었습니다. (1009, 1016, 1100 미존재)간단히 풀릴 것이라 생각했던 문제들에 예상치 못한 오류와 실수로 오답이 만들어지기도 했지만 그럴 때마다 다르게 접근하여 재미있게 문제들을 해결할 수 있었습니다.