스터디 그룹/ProjectH4C

ProjectH4C 2개월 2주차 과제 - 10문제 write-up

📖서론 

 

C언어 복습.

 

가장 기억에 남는 10문제에 대한 Write-Up을 작성하자.

사실, 파이썬과 C언어의 차이를 나타내는 그런 문제들도 많았다. 그러나 그런건 그렇게 재미가 있는 문제는 아니어서, 풀 때 복잡하다고 느낀 문제들에 대해 풀이를 진행해보자.

 

그래서 내가 고른 문제는 다음과 같다.

 

  • 1090
  • 1091
  • 1092
  • 1093
  • 1094
  • 1095
  • 1096
  • 1097
  • 1098
  • 1099

이 문제들에 대하여 자세한 Write-Up을 작성해보았다.

 


📖1090번

입력

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

출력

n번째 수를 출력한다.

 

그냥 등비수열에 관한 문제이다.

 

저 정수 a, r, n을 입력받아야 하므로 변수로 선언해줘야 한다.

그 다음, ans 이라는 변수에 출력해야 하는 값을 집어넣자

 

ans = a * pow(r, n-1);

이렇게 된다. 이때, pow 함수는 math.h를 include 해줘야 사용할 수 있다.

#include <stdio.h>
#include <math.h>

int main(){
    int a, r, n;
    long long int ans;
    scanf("%d %d %d", &a, &r, &n);

    ans = a * pow(r, n-1);

    printf("%lld", ans);
    
    return 0;
}

( ans의 경우 a, r, n의 값이 커지게 되면 정수의 범위를 벗어나게 되므로 long long int로 선언해주었다. )

 


📖1091번

입력

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

출력

n번째 수를 출력한다.

 

a, m, d, n 의 값을 입력받아야 한다. 모든 변수는 int로 선언해야 한다.

ans = a;
for(int i=0; i<n-1; i++){
    ans = ans * m + d;
}

점화식으로 표현을 할 수 있겠다. ans(n) = ans(n-1) * m + d 와 같이 ...

#include <stdio.h>

int main(){
    int a, m, d, n, ans;
    scanf("%d %d %d %d", &a, &m, &d, &n);

    ans = a;
    for(int i=0; i<n-1; i++){
        ans = ans * m + d;
    }

    printf("%d", ans);
    return 0;
}

하지만 무엇인가 잘못된 것을 확인할 수 있다.

🤢

🤮

그냥 다 long long int로 정해주자.

#include <stdio.h>

int main(){
    long long int a, m, d, n, ans;
    scanf("%lld %lld %lld %lld", &a, &m, &d, &n);

    ans = a;
    for(int i=0; i<n-1; i++){
        ans = ans * m + d;
    }

    printf("%lld", ans);
    return 0;
}

 


📖1092번

입력

같은 날 동시에 가입한 인원 3명이 규칙적으로 방문하는,
방문 주기가 공백을 두고 입력된다. (단, 입력값은 100이하의 자연수이다.)

출력

3명이 다시 모두 함께 방문해 문제를 풀어보는 날(동시 가입/등업 후 며칠 후?)을 출력한다.

 

그냥 간단하게 말하자면, 최소공배수 문제이다.

 

임의의 값 ( day ) 를 1부터 1씩 늘려가며 무한 반복을 돌아보자.

대신 a, b, c로 나누었을 때 나머지가 0이 된다면 break 해주는 것이다.

 

day = 1;
while(1){
    if( (day % a == 0) && (day % b ==0) && (day % c ==0) ){
        break;
    }
    day++;
}

이렇게 해주면 되는 것이다.

 

#include <stdio.h>

int main(){
    long long int a, b, c, day;
    scanf("%lld %lld %lld", &a, &b, &c);
    
    day = 1;
    while(1){
        if( (day % a == 0) && (day % b ==0) && (day % c ==0) ){
            break;
        }
        day++;
    }

    printf("%d", day);
    return 0;
}

📖1093번

입력

첫 번째 줄에 출석 번호를 부른 횟수인 정수 n이 입력된다. (1 ~ 10000)
두 번째 줄에는 무작위로 부른 n개의 번호(1 ~ 23)가 공백을 두고 순서대로 입력된다.

출력

1번부터 번호가 불린 횟수를 순서대로 공백으로 구분하여 한 줄로 출력한다.

 

원소 23개가 들어갈 수 있는 배열을 만들어준다음 0으로 초기화하고 값 들어올 때 마다 ++해주면 되겠다.

쉬우므로 바로 코드작성

 

#include <stdio.h>

int main(){
    int num[23]={};
    int n;
    
    scanf("%d", &n);
    for(int i=0; i<n; i++){
        int imsi;
        scanf("%d", &imsi);
        num[imsi-1]++;
    }
    
    for(int i=0; i<23; i++){
        printf("%d ", num[i]);
    }

    return 0;
}

📖1094번

입력

번호를 부른 횟수(n, 1 ~ 10000)가 첫 줄에 입력된다.
n개의 랜덤 번호(k, 1 ~ 23)가 두 번째 줄에 공백을 사이에 두고 순서대로 입력된다.

출력

출석을 부른 번호 순서를 바꾸어 공백을 두고 출력한다.

 

1093번 문제와 매우 유사하다.

배열에 값을 입력받고, 마지막 원소부터 출력을 해주면 된다.

 

#include <stdio.h>

int main(){
    int num[10000]={};
    int n;

    scanf("%d", &n);

    for(int i = 0; i < n; i++){
        scanf("%d", &num[i]);
    }

    for(int i=n-1; i>=0; i--){
        printf("%d ", num[i]);
    }

    return 0;
}

📖1095번

입력

번호를 부른 횟수(n, 1 ~ 10000)가 첫 줄에 입력된다.
n개의 랜덤 번호(k, 1 ~ 23)가 두 번째 줄에 공백을 사이에 두고 순서대로 입력된다.

출력

출석을 부른 번호 중에 가장 빠른 번호를 1개만 출력한다.

 

솔직히 드는 생각은 배열을 선언할 필요도 없을 것 같다. 최솟값만 찾는 방법으로 진행해보자.

 

#include <stdio.h>

int main(){
    int n;
    int min = 24;

    scanf("%d", &n);
    for(int i=0; i<n; i++){
        int imsi;
        scanf("%d", &imsi);
        if(imsi<min) min = imsi;
    }
    
    printf("%d", min);

    return 0;
}

해결.

 


📖1096번

입력

바둑판에 올려 놓을 흰 돌의 개수(n)가 첫 줄에 입력된다.
둘째 줄 부터 n+1 번째 줄까지 힌 돌을 놓을 좌표(x, y)가 n줄 입력된다.
n은 10이하의 자연수이고 x, y 좌표는 1 ~ 19 까지이며, 같은 좌표는 입력되지 않는다.

출력

흰 돌이 올려진 바둑판의 상황을 출력한다.
흰 돌이 있는 위치는 1, 없는 곳은 0으로 출력한다.

 

이 문제도 배열을 만들어주고 (x-1, y-1)값을 1로 바꾸어주면 될 것 같다.

 

그러므로 array[19][19]를 만들어서 해결하자.

 

#include <stdio.h>

int main(){
    int arr[19][19]={};
    int n;

    scanf("%d", &n);

    for(int i = 0; i<n; i++){
        int x, y;
        scanf("%d %d", &x, &y);
        arr[x-1][y-1]=1;
    }

    for(int i=0; i<19; i++){
        for(int j=0; j<19; j++){
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}

📖1097번

입력

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

출력

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

 

십자 뒤집기가 무엇일까.

십자 뒤집기란 해당 칸에 흑돌이 있으면 백돌로 바꾸고, 백돌이 있다면 흑돌로 바꾸는 것을 의미한다.

십자 뒤집기란 해당 칸을 기준으로 가로 세로 모든 칸의 돌을 뒤집는 것이다. (이걸 위의 줄로 해석해서 계속 틀렸다.)

본 문제에서는 흑돌과 백돌에 대한 구분을 0과 1로 진행한다.

 

그럼 돌을 뒤집는 것은 삼항연산자로 해결할 수 있다.

 

#include <stdio.h>

int main(){
    int arr[19][19]={};
    int n;
    
    for(int i=0; i<19; i++){
        for(int j=0; j<19; j++){
            scanf("%d ", &arr[i][j]);
        }
    }

    scanf("%d", &n);

    for(int i = 0; i<n; i++){
        int x, y;
        scanf("%d %d", &x, &y);
        //arr[x-1][y-1] = (arr[x-1][y-1]) ? 0 : 1;
        for(int j=0; j<19; j++){ //x
            //arr[i][y-1] = arr[i][y-1] ? 0 : 1;
            if(arr[j][y-1] == 1) arr[j][y-1] = 0;
            else arr[j][y-1] = 1;
        }
        for(int j=0; j<19; j++){ //y
            //arr[x-1][j] = arr[x-1][j] ? 0 : 1;
            if(arr[x-1][j] == 1) arr[x-1][j] = 0;
            else arr[x-1][j] = 1;
        }
        //arr[x-1][y-1] = (arr[x-1][y-1]) ? 0 : 1;
        /*
        if(arr[x-1][y-1] == 1) arr[x-1][y-1] = 0;
        else arr[x-1][y-1] = 1;
        */
    }

    for(int i=0; i<19; i++){
        for(int j=0; j<19; j++){
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}

📖1098번

입력

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

입력값의 정의역은 다음과 같다.

1 <= w, h <= 100
1 <= n <= 10
d = 0 or 1
1 <= x <= 100-h
1 <= y <= 100-w

출력

모든 막대를 놓은 격자판의 상태를 출력한다.
막대에 의해 가려진 경우 1, 아닌 경우 0으로 출력한다.
단, 각 숫자는 공백으로 구분하여 출력한다.

 

#include <stdio.h>
 
int main()
{
    int matrix[100][100] = {};  
    
    int h,w,n,l,d,x,y;
    
    scanf("%d %d",&h,&w); 
    scanf("%d",&n);       
    
    for(int i = 1; i <= n; i++){
        scanf("%d %d %d %d",&l,&d,&x,&y);
        if(d == 0){
            for(int j = 0; j<l; j++){
                matrix[x][y+j] = 1;
            }
        }
        else{
            for(int j = 0; j<l; j++){
                matrix[x+j][y] = 1;
            }
        }
    }
    
    for (int i = 1; i <= h; i++) 
    {
        for (int j = 1; j <= w; j++) 
        {
            printf("%d ", matrix[i][j]); 
        }
        printf("\n");
    }
    
    return 0;
}