백준 9020번 C언어

Boomerang·2021년 8월 11일
0

알고리즘

목록 보기
10/10
post-thumbnail

12:54 ~ 13:35 41분

기본적인 생각

  1. array형식으로 한번에 다 정해두고 하는 형식으로는 두 소수차 가장 작은것을 표현하기 힘들 것 같다라고 생각했고 for문을 통해 조건을 연속적으로 주어야겠다 라고 생각했다. -> 생각바뀜.
  2. wiki에 들어가서 골드바흐 넘버에 대해 검색해봤다.
  3. 두 소수차가 가장 차이가 적게 되려면, 반복을 통해 첫번째 소수가 커야 할 것이다
    ex) 10 = 3 + 7 = 5 + 5 이기때문에 첫 소수가 3이 아니라 5. 이것은 반복을 해서 비교해야 할 것이라는 말.


골드바흐 넘버



50까지의 짝수는

4 = 2+2
6 = 3+3
8 = 3+5
10 = 3+7 = 5+5
12 = 5+7
14 = 3+11 = 7+7
16 = 3+13 = 5+11
18 = 5+13 = 7+11
20 = 3+17 = 7+13
22 = 3+19 = 5+17 = 11+11
24 = 5+19 = 7+17 = 11+13
26 = 3+23 = 7+19 = 13+13
28 = 5+23 = 11+17
30 = 7+23 = 11+19 = 13+17
32 = 3+29 = 13+19
34 = 3+31 = 5+29 = 11+23 = 17+17
36 = 5+31 = 7+29 = 13+23 = 17+19
38 = 7+31 = 19+19
40 = 3+37 = 11+29 = 17+23
42 = 5+37 = 11+31 = 13+29 = 19+23
44 = 3+41 = 7+37 = 13+31
46 = 3+43 = 5+41 = 17+29 = 23+23
48 = 5+43 = 7+41 = 11+37 = 17+31 = 19+29
50 = 3+47 = 7+43 = 13+37 = 19+31
위와 같이, 두 개의 소수의 합으로 표현할 수 있다. 그러나 모든 짝수에서 가능한지는 아직까지 해결하지 못하고 있다.
위키 참조

코드에 번호에 맞춘 주석이 있습니다

  1. 다시 생각해보면 짝수의 형식이니까 (구해야하는 짝수 - 작은소수 순서대로 = 짝수) 면 안되고 홀수가 나와야하고, 이 작은소수 순서대로를 점차 늘리면 될것이다.
    (왜냐하면 두 소수가 더해서
  2. 일단 구해야하는 짝수가 들어갔을때, 가장 작은 소수를 나오게하고, 그 다음 작은 소수를 나오게하는 것을 짜봐야겠다.
  3. 5번에서 다시 4번을 만들어 봐야겠다.
  4. check - i - i 차이가 가장 작은것이, 두 소수의 차이가 작은 것이다. 따라서 check - 2 * i = min으로 설정해야겠다.
  5. 디버깅해보니 i가 7이고 check - i 가 3일경우 음수가 나와서 min값을 제대로 알지 못한다. 따라서 stdlib헤더의 abs함수를 사용한다.
  6. 디버깅해보니 4가 들어갔을때 check - i가 짝수라 무시하게 해뒀다. 4초과일 경우 무조건 check - i 가 소수가 아닌데, 4일경우는 2 + 2로 소수가 가능하다.

3줄 요약

1) check은 입력값
2) 여기서 말하는 i는 작은소수를 순서대로 표현한것
2) |i - (check - i)|가 가장 작은 수를 찾으면 된다.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
	int arr[100001] = { 0, };

	int n, check, min = 10000, low, high;

	arr[1] = 1;	// 1은 소수가 아니기때문에

	for (int i = 2; i < 100001; i++) {
		for (int j = 2; i * j < 100001; j++) {
			arr[i * j] = 1;
		}
	}
	scanf("%d", &n);

	while (n--) { 
		scanf("%d", &check);

		//4번 
		/*
		for (int i = 2; i < check; i++) {
			if(arr[i] == 0) printf("%d ", i);
		}
		*/

		// 5번
		/*
		for (int i = 2; i < check; i++) {
			if (arr[i] == 0) {
				if ((check - i) % 2 == 0) { // 짝수일 경우에는 무시

				} // 아닐 경우에는 printf
				else {
					printf("%d ", i);
				}
			}
		}
		*/


		for (int i = 2; i < check; i++) { // 6번
			if (arr[i] == 0) {
				if ((check - i) % 2 == 0) { // 짝수일 경우에는 무시 라고 생각했는데 4가 들어왔을때는 인정.
					if (check - i == 2) {	// 9번
						low = high = 2;
					}
				} // 아닐 경우 + check - i도 소수일때 
				else if(arr[check-i] == 0){	// check-i가 0이어야지 소수
					if (min > abs(check - 2 * i)) {	// 7번, 8번
						min = abs(check - 2 * i);
						low = i;
						high = check - i;
					}

					//printf("%d ", i);
				}
			}
		}

		printf("%d %d\n", low, high);
		low = high = 0;
		min = 100000;
	}
	

	return 0;
} 

문제 풀이 후 알게된 점

  1. 0 % 2 == 0이다
  2. stdlib.h header에 abs는 int가 들어오면 int 절대값 return.
  3. math.h header에 fabs는 double 절대값 return
  4. 처음에 생각했던 부분이 잘못 되었는지 잘 모르겠으면 다시 그 아이디어를 조합해서 만들어보면 수월하게 문제가 풀릴 것이다.
profile
Hello World

0개의 댓글