PS 문제풀이

1/30~2/2 : 2908번, 2920번, 3052번

희디 2022. 1. 31. 04:35

<2908번> : 상수 

#include <stdio.h>

int main(){
    int num1[3], num2[3];
    scanf("%d %d", &num1, &num2);
    for(int k=2; k>=0; k-- ){
        if(num1[k]>num2[k]) printf("%d", num1);
        else if(num1[k]==num2[k])
    }
}

원래는 백의 자리와 일의 자리를 인덱스 차원으로 바꾸고 비교하려고 했는데 숫자를 문자열로 바꾸고 하려고 하는 등 복잡함이 많아서 고민하다가 생각이 안 나서 구글링을 해보니까 새롭게 숫자를 만드는 방법이 있었다. 그러기 위해서 숫자 예를 들면 543이면 5*100+4*10+3*1 이렇게 더하기 식으로 나눠서 더해야 한다는 것을 깨닫고 코드를 수정했다. 

#include <stdio.h>
int main() {
	int n1, n2;
	scanf("%d %d", &n1, &n2);
	n1 = 100 * ((n1 % 100) % 10) + 10 * ((n1 % 100) / 10) + n1 / 100;
	n2 = 100 * ((n2 % 100) % 10) + 10 * ((n2 % 100) / 10) + n2 / 100;
	
	if (n1 > n2) printf("%d", n1);
	else if (n1 < n2) printf("%d", n2);

	return 0;
}

먼저 숫자 2개를 받을 변수 n1과 n2를 선언하고 각각 스캔을 받는다. 그리고 일의 자리에 100을 곱하고 십의 자리에 10을 곱하고 백의 자리를 더해 거꾸로 된 숫자 2개를 구해 다시 n1과 n2에 넣는다. 그리고 조건문 if문을 사용해서 n1이 클 경우 n1(위에서 n1의 값이 이미 거꾸로 변함)을 출력하고 n2가 크면 n2를 출력하도록 printf를 해주었다.

그랬더니 PASS!!

** 각 자리를 다룰 때 무조건 적으로 인덱스만 생각하지 말고 숫자일 경우, 쪼개서 생각해보자 **

 

<2920번> : 음계

#include <stdio.h>

int main() {
	int num[8];
	for (int k = 0; k<8; k++) {
		scanf("%d", &num[k]);
	}
	int result=0;

	for (int k = 0; k<7; k++) {
		if (num[0] == 1 && num[k + 1] - num[k] == 1) result=1;
		else if (num[0] == 8 && num[k] - num[k+1] == 1) result=2;
		else result=3;
	}
	if (result==1) printf("ascending");
	else if (result==2) printf("descending");
	else printf("mixed");
}

처음에 이렇게 했다가 8 6 7 5 4 3 2 1이 descending이 나온 것을 보고 고침 

#include <stdio.h>

int main() {
	int num[8];
	for (int k = 0; k<8; k++) {
		scanf("%d", &num[k]);
	}
	int result1 = 0;
	int result2 = 0;

	for (int k = 0; k<7; k++) {
		if (num[0] == 1 && num[k + 1] - num[k] == 1) result1++;
		else if (num[0] == 8 && num[k] - num[k+1] == 1) result2++;
		else result3++;
	}
	if (result1 == 7) printf("ascending");
	else if (result2 == 7) printf("descending");
	else printf("mixed");
}

먼저 음계 8개를 담을 정수형 배열을 선언 및 스캔을 받는다. 그리고 result1부터 3까지 선언을 하고 0으로 초기화해준다. ascending은 1부터 시작해서 1씩 증가(8개의 모든 수가 증가) 해야 하므로 처음 시작이 1이고 8까지 두 수를 비교한다면 7번 비교하게 되므로 7번 반복을 해서 차이가 1이면 result1++을 해주고 7이 된다면 ascending을 한다. descending은 처음이 8인것으로 바꿔서 계산하면 된다. result1,2값이 7값이 아니라면 mixed가 나오게 else문을 사용해줬다. 

<3052번> : 나머지

#include <stdio.h>
int main() {
	// 필요한 수는 10개. 
	// 각각을 42로 나눠서 나머지 파악하고 
	// 다른 값이 몇 개 있는지 출력하는 프로그램. 
	// 7 6 39 20 8 3 8 10 33 21 : 2개
	// 1) 몫이 1이고 나머지가 0. 
	// 2) 
	int num[10];
	int count = 10;
	for (int k = 0; k < 10; k++) {
		scanf("%d", &num[k]);
		num[k] = num[k] % 42;
	}
	for (int k = 0; k <9; k++) {
		for (int j = k+1; j < 10; j++) {
			if (num[j] / num[k] == 1 && num[j] % num[k] == 0) {
				count--;
			}
		}
	}
	printf("%d", count);
}

그냥 숫자가 같다는 것을 컴퓨터가 아는데 굳이 나누기와 나머지 등을 사용한다는 것은 너무 깊게 생각한 듯.. 

그래서 다시 코드를 수정했다. 

#include <stdio.h>

int main() {
	int num[10];
	int cnt = 10;
	for (int k = 0; k < 10; k++) {
		scanf("%d", &num[k]);
		num[k] = num[k] % 42;
	}

	for (int i = 0; i < 10; i++) {
		for (int j = i+1; j <10; j++) {
			if (num[i] - num[j] == 0) {
				cnt--;
			}
		}
		
	}
	printf("%d", cnt);
}

이 코드는 같을 때 cnt 10에서 점점 1을 줄이는 것인데 실패했다. 

num[i]가 바뀔때마다 중복이 되는 기준에 대한 초기화(0으로)가 없어서 오류가 난 듯하다. 

#include <stdio.h>

int main() {
	int num[10];
	int cnt = 0;
    
	for (int k = 0; k < 10; k++) {
		scanf("%d", &num[k]);
		num[k] = num[k] % 42;
	}
    
	for (int i = 0; i <10; i++) {
        int many=0; 
		for (int j = i+1; j <10; j++) { 
			if (num[i] ==num[j]) { 
                many++;  // 중복이 있다! 
			}  
		}
        if(many==0) cnt++;  
	}
    printf("%d", cnt);
}

처음에 숫자 10개를 담을 배열 10개를 선언하고 cnt를 0으로 선언한다. 그리고 각 수를 스캔 받고 저장된 값에서 42로 나눈 나머지 값으로 바꿔준다. 다음으로 반복문에서

num[0]과 num[1]~num[9]와 num[1]과 num[2]~num[9]끼리 ... 비교할 것이므로 변수 2개를 써서 i는 0부터 9, j는 i+1부터 9까지 반복문을 돌려서 서로 같다면, 중복을 나타내는 many에 1을 더한다. many는 반복문이 돌아갈때마다(num[i]값이 변할 때마다) 0으로 초기화 되어야 한다. num[i]을 기준으로 num[i]와 중복이 있는지 확인하는 것이 목적이므로 반복문 돌때마다 초기화 필수!! 그래서 i의 반복문이 끝날때 many가 0이라면(중복이 없으면) cnt에 1을 더해서 최종적으로 cnt를 출력해준다. 

 

+) 백준 2577번에 있는 13번 줄에 있는 나머지의 수의 인덱스에 바로 들어가서 확인하는 방법도 있다.