Layer7 동아리 과제

C 4차시 과제

msh1307 2022. 4. 16. 12:41

-1065- 문제


어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오. (N<=1,000)

 

-1065- 풀이


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
 
int main()
{
    int cnt=0;
    int n;
    int a,b,c;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        if(i<10)cnt++;
        else if(i<100)cnt++;
        else if(i<1000){
            a= i%10;
            b= (i%100)/10;
            c= i/100;
            if(a-b==b-c)cnt++;
        }
    }
    printf("%d",cnt);
    return 0;
}
cs

 

한수를 세기위해 cnt라는 변수를 따로 만들었다.

변수 n을 선언해서, n에 입력 값을 넣어줬다.

한 자릿수혹은 두 자릿수라면 어차피 한수이므로 cnt++을 해줬다.

그 이후는 따로 자릿수를 각 변수에 넣어준뒤, 그 차이를 비교해줬다.

문제에서 N은 1000보다 작거나 같으므로 1000이 나오면 어차피 한수가 아니라서 조건문으로 따로 걸러주지는 않았다.

 

-10872- 문제


0보다 크거나 같은 정수 N이 주어진다. 이때, N!을 출력하는 프로그램을 작성하시오.(0 ≤ N ≤ 12)

 

-10872- 풀이


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

 

처음 문제를 풀때 N을 보고 대충 int의 범위안에 안들어갈 줄 알고 long long을 사용했다.

하지만 지금보니 N이 최대 12까지 들어갈 수 있으니, int형으로도 충분히 풀 수 있는 문제였다. 

재귀 함수를 사용해서 풀었다. 

a==0이거나 a==1이면 어차피 0 팩토리얼이나 1 팩토리얼이므로 둘다 1을 리턴해주었다. 

만약 둘다 아니라면 f(a-1)을 호출하고 a를 곱해주었다. 

long long을 사용했기 때문에 포맷스트링은 %lld를 사용했다.

 

-21966- 문제


드높은 남산 위에 우뚝 선

(중략)

세워라 반석 위에

선린의 터를

1개 이상의 문장들이 주어진다. 아래 규칙에 따라 문장들의 중간 부분을 적당히 생략해 25글자 이내로 요약해서 출력하는 프로그램을 작성하자.

단, 입출력의 편의를 위해 문장들을 공백 없이 모두 붙여 구성한 문자열 S가 대신 주어진다. 문자열의 첫 글자부터 가장 먼저 만나는 '.'(마침표)까지, 그리고 각 '.'의 다음 글자부터 가장 먼저 만나는 '.'까지를 한 문장으로 생각하기로 하자. 예를 들어 주어진 문자열 S가 'IamInevitable.IamIronMan.'이라면 'IamInevitable.'이 한 문장, 'IamIronMan.'이 한 문장이다.

규칙은 다음과 같다.

  1.  S의 길이가 25 이하면 S를 그대로 출력한다.
  2.  S의 길이가 25 초과이면, S의 앞에서부터 11글자, 뒤에서부터 11글자를 제외하고 나머지 부분을 생각하자. 이 나머지 부분이 모두 같은 문장에 속한다면, 생략한 뒤 '...'('.' 3개)으로 바꿔서 출력한다.
  3. 위 두 경우에 해당되지 않는다면 S를 앞에서부터 9글자, 뒤에서부터 10글자만 남기고 중간은 '......'('.' 6개)으로 바꿔서 출력한다.

 

-21966- 풀이


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
#include<stdio.h>
int main(){
  int N; 
  int x=0
  char str[1000001]="";
  scanf("%d",&N);
  scanf("%s",str);
  if(N<=25){
    printf("%s",str);
  }
  else {
    for(int i=12;i<N-12;i++){
      if(str[i]=='.')x=1
    }
    
    if(x==0){
      for(int i=0;i<11;i++){
        printf("%c",str[i]);
      }
      printf("...");
      for(int i=N-11;i<N;i++){
        printf("%c",str[i]);
      }
      return 0;
    }
    for(int i=0;i<9;i++)printf("%c",str[i]);
    printf("......");
    for(int i=N-10;i<N;i++)printf("%c",str[i]);
  }
}
 
cs

 

문자열은 뒤에 널 문자 때문에 1을 더 크게 잡아주었다. 

만약 25보다 작거나 같으면 첫 번째 조건에 따라서 그냥 출력해주었다. 

만약 아니라면 25초과이니 두 번째 조건을 검사해주고, 맞다면 두 번째 조건에 맞게 출력해주고, 아니라면 세 번째 조건에 맞게 출력을 해줬다.

.을 통해서 문장을 구분하니 for문을 통해서 문장의 양 끝을 제외하고 검사해줬다.

그 이유는 양 끝에 .가 있어도 어차피 한 문장안에 속하기 때문이다. 

 

-14467- 문제


닭이 길을 건너간 이유는 과학적으로 깊게 연구가 되어 있지만, 의외로 소가 길을 건너간 이유는 거의 연구된 적이 없다. 이 주제에 관심을 가지고 있었던 농부 존은 한 대학으로부터 소가 길을 건너는 이유에 대한 연구 제의를 받게 되었다.

존이 할 일은 소가 길을 건너는 것을 관찰하는 것이다. 존은 소의 위치를 N번 관찰하는데, 각 관찰은 소의 번호와 소의 위치 하나씩으로 이루어져 있다. 존은 소를 10마리 가지고 있으므로 소의 번호는 1 이상 10 이하의 정수고, 소의 위치는 길의 왼쪽과 오른쪽을 의미하는 0과 1 중 하나다.

이 관찰 기록을 가지고 소가 최소 몇 번 길을 건넜는지 알아보자. 즉 같은 번호의 소가 위치를 바꾼 것이 몇 번인지 세면 된다.

 

-14467- 풀이


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
int main()
{
    int idx=-1,b=-1,n,cnt=0;
    int arr[11]={0};
    for(int i=0;i<11;i++){
        arr[i]=-1;
    }
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d %d",&idx,&b);
        if(arr[idx]==-1){
            arr[idx]=b;
        }
        else {
            if(arr[idx]!=b){
                arr[idx]=b;
                cnt++;
            }
        }
    }
    printf("%d",cnt);
    return 0;
}
cs

 

배열을 처음에 -1로 초기화해서 처음 소의 위치를 저장했는지 안했는지 확인을 하고, 만약 초기 위치가 저장이 안되었다면 저장했다. 

배열을 arr[11]로 잡은 이유는 편의를 위해서 arr의 0 번째 요소를 사용하지 않기 때문이다.

그 후 만약 저장된 값과 다음에 나온 값이 다르다면 위치를 저장하고, 아니라면 소가 아직 제자리에 있다는 것이니 세지 않았다. 

마지막으로 cnt를 출력했다. 

 

-19941- 문제


기다란 벤치 모양의 식탁에 사람들과 햄버거가 아래와 같이 단위 간격으로 놓여 있다. 사람들은 자신의 위치에서 거리가 K 이하인 햄버거를 먹을 수 있다.

햄버거 사람 햄버거 사람 햄버거 사람 햄버거 햄버거 사람 사람 햄버거 사람
1 2 3 4 5 6 7 8 9 10 11 12

위의 상태에서 K=1인 경우를 생각해보자. 이 경우 모든 사람은 자신과 인접한 햄버거만 먹을 수 있다. 10번의 위치에 있는 사람은 11번 위치에 있는 햄버거를 먹을 수 있다. 이 경우 다음과 같이 최대 5명의 사람이 햄버거를 먹을 수 있다.

  • 2번 위치에 있는 사람: 1번 위치에 있는 햄버거
  • 4번 위치에 있는 사람: 5번 위치에 있는 햄버거
  • 6번 위치에 있는 사람: 7번 위치에 있는 햄버거
  • 9번 위치에 있는 사람: 8번 위치에 있는 햄버거
  • 10번 위치에 있는 사람: 11번 위치에 있는 햄버거
  • 12번 위치에 있는 사람: 먹을 수 있는 햄버거가 없음

K=2인 경우에는 6명 모두가 햄버거를 먹을 수 있다.

  • 2번 위치에 있는 사람: 1번 위치에 있는 햄버거
  • 4번 위치에 있는 사람: 3번 위치에 있는 햄버거
  • 6번 위치에 있는 사람: 5번 위치에 있는 햄버거
  • 9번 위치에 있는 사람: 7번 위치에 있는 햄버거
  • 10번 위치에 있는 사람: 8번 위치에 있는 햄버거
  • 12번 위치에 있는 사람: 11번 위치에 있는 햄버거

식탁의 길이 N, 햄버거를 선택할 수 있는 거리 K, 사람과 햄버거의 위치가 주어졌을 때, 햄버거를 먹을 수 있는 사람의 최대 수를 구하는 프로그램을 작성하시오.

 

-19941- 풀이


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 n,k;
    int cnt=0,ate=0;
    char str[20000]={0};
    scanf("%d %d",&n,&k); 
    scanf("%s",str);
    for(int i=0;i<n+1;i++){
        if(str[i]=='P'){
            for(int j=i-k;j<i;j++){
                if(j>=0){
                    if(str[j]=='H'&&ate==0){
                        cnt++;
                        ate = 1;
                        str[j]='X';
                    }
                }
            }
            for(int j=i+1;j<=i+k;j++){
                if(j<n){
                    if(str[j]=='H'&&ate==0){
                        cnt++;
                        ate = 1;
                        str[j]='X';
                    }
                }
            }
            ate=0;
        }
    }
    printf("%d",cnt);
    
}
 
cs

먼저 최대 값을 구하려면, P가 햄버거를 먹을 때 기본적으로 왼쪽을 먼저 탐색하고 가장 왼쪽에 있는 것을 먹어야 한다.

만약 왼쪽에 없어서 오른쪽을 탐색하게 된다면, 최대한 왼쪽에 있는 햄버거를 먹어야 한다.

P가 햄버거를 먹었다면, 탐색을 중단해야한다. 또한 먹은 햄버거는 다음 P가 햄버거를 탐색할때, 제외되어야한다.

 

먼저 식탁의 길이와, 선택할 수 있는 거리를 받는다. 

변수 ate를 선언하고 초기 값을 0으로 잡아준다. 이 변수 ate는 나중에 햄버거를 여러개 먹지 않도록 하기위해서 사용되었다.

만약 P가 있다면, 초기 값을 가장 왼쪽으로 잡음으로써 항상 가장 왼쪽부터 탐색을 시작하게 된다. 만약 H(햄버거)가 있고 ate가 0이라면 cnt를 증가시키고 ate를 1로 바꾸어준다. 또한 나중에 탐색에서 제외되야하기 때문에 H를 X로 바꿔준다. 

또한 만약 왼쪽을 탐색했는데 햄버거가 없다면, 오른쪽을 탐색해야한다. 오른쪽중 가장 왼쪽을 초기 값으로 잡아서 항상 가장 왼쪽의 햄버거를 찾을 수 있도록 했다. 

 

이 모든 과정이 끝난 뒤, ate를 0으로 다시 바꿔줬다. 바꿔줘야 ate==0이라는 조건에 걸리지 않기 때문이다.

 

'Layer7 동아리 과제' 카테고리의 다른 글

웹 해킹 6차시 과제  (0) 2022.05.19
웹 해킹 4차시 과제  (0) 2022.05.16
웹 해킹 2차시 과제  (0) 2022.05.08
웹 해킹 3차시 과제  (0) 2022.05.05
C 3차시 과제  (0) 2022.04.12