BOJ(백준)

[C언어] 백준 - 1차원 배열 (10818, 2562, 2577, 3052)

ruming 2020. 9. 30. 01:56

[10818] 최소, 최대 

N개의 정수를 입력 받아 최솟값과 최댓값을 출력하는 문제

N (1 ≤ N ≤ 1,000,000), 모든 정수는 -1,000,000보다 크거나 같고, 1,000,000보다 작거나 같은 정수

#include <stdio.h>
#include <stdlib.h>
int main(void){
	int *n;
	int N, i, max, min;
	scanf("%d", &N);
	n = (int*)malloc(sizeof(int)*N);
	for(i=0; i<N; i++)	scanf("%d", &n[i]);
	max = n[0], min = n[0];
	for(i=1; i<N; i++)	max = max > n[i] ? max : n[i];	
	for(i=1; i<N; i++)	min = min < n[i] ? min : n[i];
	printf("%d %d\n", min, max);
	return 0;
}

지금 생각난건데 for문 하나 안에서 max, min 한번에 구할 수 있는데 for문을 두번이나 돌렸다. 어쩐지 오래걸리더라니

 

이거 메모리 할당받지 않으면 N 범위가 너무 커서 (1,000,000까지) 비효율적이라 사용하긴 했는데

n[1000000]으로 하면 dev에서 입력이 안되고 끝나버린다. 백준에서는 정답으로 처리됐다.

#include <stdio.h>
int main(void){
	int n[1000000];
	int N, i, max, min;
	scanf("%d", &N);
	for(i=0; i<N; i++)	scanf("%d", &n[i]);
	max = n[0], min = n[0];
	for(i=1; i<N; i++)	max = max > n[i] ? max : n[i];	
	for(i=1; i<N; i++)	min = min < n[i] ? min : n[i];
	printf("%d %d\n", min, max);
	return 0;
}

 

[2562] 최댓값

9개의 정수를 입력 받아 최댓값과 그 최댓값이 몇번째인지 출력하는 문제

주어지는 자연수는 100 보다 작다.

#include <stdio.h>
int main(void){
	int n[9];
	int i, max, num;
	for(i=0; i<9; i++)	scanf("%d", &n[i]);
	max = n[0];
	for(i=1; i<9; i++)	max = max > n[i] ? max : n[i];
	printf("%d ", max);	
	for(i=0; i<9; i++){
		if(max == n[i])	printf("%d\n", i+1);
	}
	return 0;
}

 

 

 

 

[2577] 숫자의 개수

세 정수 a, b, c를 입력받고 곱한 수를 0~9까지 숫자가 몇개쓰였는지 출력하는 문제

 A, B, C는 모두 100보다 크거나 같고, 1,000보다 작은 자연수이다.

#include <stdio.h>
int main(void){
	int a, b, c, abc, i;
	int num[10] = {0};
	scanf("%d%d%d", &a, &b, &c);
	abc = a*b*c;
	while(abc>=0){
		num[abc%10]++;
		abc/=10;
		if(abc>=0&&abc<10){
			num[abc%10]++;
			break;
		}
	}
	for(i=0; i<10; i++)	printf("%d\n", num[i]);
	return 0;
}

0부터 9까지 숫자를 셀 배열 num을 선언하고, a b c를 곱한 값 abc를 끝에서부터 한자리씩 배열에 넣었다.

 

#include <stdio.h>
int main(void) {
	int a, b, c, abc, i;
	int num[10] = { 0 };
	scanf("%d%d%d", &a, &b, &c);
	abc = a * b * c;
	while (abc > 0) {
		num[abc % 10]++;
		abc /= 10;
	}
	for (i = 0; i < 10; i++)	printf("%d\n", num[i]);
	return 0;
}

과거의 내가 if문을 왜 썼나 생각해봤는데 마지막에 남는 수가 0일 때를 대비해서 쓴 것 같다. 맨 앞자리 숫자가 0인 경우는 없으니까 while문 조건을 abc>0으로 바꿔주고 if문을 지워줬다. 정답처리됐다.

 

[3052] 나머지

두 자연수 A와 B가 있을 때, A%B는 A를 B로 나눈 나머지 이다. 예를 들어, 7, 14, 27, 38을 3으로 나눈 나머지는 1, 2, 0, 2이다.

수 10개를 입력받은 뒤, 이를 42로 나눈 나머지를 구한다. 그 다음 서로 다른 값이 몇 개 있는지 출력하는 프로그램을 작성하시오.

#include <stdio.h>
int main(void){ 
	int i, n = 0;
	int a, b[42] = {0};
	for(i=0; i<10; i++){
		scanf("%d", &a);
		b[a%42] = 1;
	}
	for(i=0; i<42; i++){
		if(b[i])	n++;
	}
	printf("%d", n);
	return 0;
}

42로 나눈 나머지는 0~41까지 42개가 있을테니 42크기의 배열 b를 잡았다. for문을 돌려 나머지를 배열에 넣는데 서로 다른 값만 찾으면 되므로 +1하지 않고 1로 설정했다. for문으로 배열 안에서 나머지가 있으면 n으로 개수를 센다.

 

아래는 처음에 제출했던 코드인데 10크기의 배열을 사용한 방식이다. 나머지를 배열에 다 저장하고 배열 안에서 서로 다른 수를 센다. 

#include <stdio.h>
int main(void){ 
	int i, j, flag = 0, sum = 0;
	int ten[10] = {0};
	for(i=0; i<10; i++){
		scanf("%d", &ten[i]);
		ten[i] %= 42;
	}
	for(i=0; i<10; i++){
		for(j=i+1; j<10; j++){
			if(ten[i] == ten[j]){
				flag = 1;
				break;
			}
		}
		if(!flag)	sum++;
		flag = 0;
	}
	printf("%d", sum);
	return 0;
}

서로 다른 수를 확인하는 방식이 상당히 비효율적이다. 수가 10개밖에 되지 않으니 정렬해서 센다던가 하는 방식이 더 효율적일 것 같다. 아니면 flag로 하나하나 확인하는 것보다 서로 같은 수일 때마다 10에서 하나씩 빼버리는 방식이 더 좋았을 것 같다.

 

#include <stdio.h>
int main(void){ 
	int a, b;
	int i, j, sum = 0;
	int ten[10] = {0};
	for(i=0; i<10; i++){
		scanf("%d", &ten[i]);
		ten[i] %= 42;
	}
	for(i=0; i<10; i++){
		sum++;
		for(j=i+1; j<10; j++){
			if(ten[i] == ten[j]){
				sum--;
				break;
			}
		}
	}
	printf("%d", sum);
	return 0;
}

위 코드에서 서로 다른 숫자 세는 방법을 바꾼 코드다. 같은 수가 있을 때마다 -1하고있다.