백준 4673 아주 미친놈; by 꽁치


  내가 바본지 뭔지 이문제갖고 4시간 고민한 듯하다. 
 이상한 똥고집은 있어갖고 안풀려서 화나뒤질뻔하기 전까지 생각하다 안되겠을 때 유튜브 강의를 찾아봤다. 강의는 문제풀이까지 보고 코드는 내것과 다른사람것 참고해서 어찌저찌 고쳐썼다.. 

 일단 그놈의 코드부터


 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<iostream>
#define N 10001
#include<cstdio>
using namespace std;
bool arr[N];
int sum = 0;
int num1 = 0; //생성자 있는 수
int Kaprekar(int n){
sum = n;
while(1){
if(n==0) break;
sum += n%10;
n = n/10;
}
return sum;
}
int main(void){
for(int i= 1;i<N;i++){
num1 = Kaprekar(i);
if(num1 < N)
{
arr[num1] = true;
}
}
for(int i = 1; i<N;i++){
if(!arr[i])
printf("%d\n",i);
}

return 0;


}


d(n)의 값을 구하는 식은 어렵지 않았다. n%10과 n/10병행해서 n자리수까지 for문을 쓰면 되니까.. 
하지만 내 욕심은 하나하나 확인하면 오래걸릴 것 같아 생성자> d(n)의 역 formula 를 구하려고 애썼던 것이다.. 주어지는 수 n의 가장 가까운 셀프넘버를 빼고 더하고 곱하고 다해보았지만 공식을 구해내기는 어려웠다. (실은 이거 생각하는데 2시간 쓴듯) 

정리해 보자면 내가 생각했던 틀린 알고리즘은 다음과 같다. 
1. 하나하나 확인하기 
일단 n은 1부터 10000까지. n%10 n/10 계산하는 함수 solution(); return k;

 배열 a1[]에 k값을 하나하나 넣는다. 여기까진 생각이 간 것 같은데.. 생성자를 어떻게 걸러내냐에서 머리가 멈췄었다. 

2. 역formula 구하기 
랜덤값 수 a, b가 있다고 가정하고, 주어지는 값n(여기서는 생성자를 가지는 수를 탐색하기위해, 그러니 n은 생성자를 가진 수를 가정으로함)

if (n -(a+b) == a*10+b || n -(a+b) == a+b*10)면 n = 생성자를 가지는 수 == !selfnum이 되는 거라 생각했지만,, 숫자 범위가 두자리수만 있는 것이 아니라 금방 기각했다. 

2-1. 여기서 역 fomula를 구하려고 별짓을 다했는데..ㅋㅋ 
현재 밝혀진 self number들은 1,3,5,7,9,20,31,42,53,64,775,86,97이었는데, selfnum[]배열을 만들어서, 저기 넘버들 먼저 배열에 넣고.. 
n과 가장 가까운 selfnumber를 빼고 더하고곱하고 해서 공식이 나오면(ㅋㅋ) self num[i] 에 신규로 갱신해서 10000까지 계속 진행하려했다.
공식이 있었어도 많이 복잡했을 듯.. 


여튼 오늘 bool 을 처음 쓰게 되었는데, 함수공부를 체계적으로 해야겠다는 생각이 들었다.  따로 배운건 배열까지가 끝이라서 함수에 대한 지식은 턱없이 부족하고 알고리즘을 구현할 때에도 아는 문법이 없으니 정말..정말.. 한계가 많았다. 틈만나면 러닝타임 오버? 뜨고.. 
좀 웃기고 빡쳤던 일 중 하나는.. 이 코드를 저지시스템에 냈는데 괄호를 잘못닫아서 값이 2번 출력되서 출력초과가 떴었다. 난 또 코드가 잘못된줄 알고 머리를 싸맸지만.. 괄호 문제였다는 것. 

  배열 문제 이후로 문제푸는데 시간이 너무 오래걸린다.. 

문법도 공부해서 정리하는 글을 써야겠다. 

이번 문제 코드는 이곳에서 많이 도움받았다. https://blockdmask.tistory.com/160 감사합니다!
  

덧글

댓글 입력 영역