문제출처 : https://www.acmicpc.net/problem/2331


1. 문제요약

- D[1] = A

  D[n] = D[n-1]의 각 자릿수의 숫자를 P번 곱한 수들의 합


- A = 57, P = 2일 때,

  {57, 74(5^2 + 7^2 = 25 + 49), 65, 61, 37, 58, 89, 145, 42, 20, 4, 16, 37, ...}

  여기서 {57, 74, 65, 61}을 제외한 숫자는  반복된다.


- 1 <= A <= 1,000

- 1 <= P <= 5


- 반복되지 않는 숫자의 개수는?


2. 접근방법

- 두 가지를 생각해 봤는데


1) V[num] = cnt


2) V[cnt] = num


- 1) 방법은 해당 특정 숫자가 몇번째 인지 저장해서 한번 방문했던 숫자를 재 방문하면 해당 cnt를 리턴

      num이 얼마나 커질지 모름....


- 2) 방법은 cnt에 num을 가지고 있음

      배열의 크기는 최대 1000을 넘지 않지만

      해당 숫자가 이전에 있었는지를 연산 후에 매번 확인해줘야함.


3. 시간복잡도

- 1)은 O(N) : 1,000

- 2)는 O(N^2) : 1,000,000


4. 회고

- 난 1)번 방법으로 풀긴했는데 음... 2)번 방법이 좀 더 확실할 것같다. 

  1)번은 배열 크기를 알 수가 없으므로



소스코드 : 1)번 방법



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 9466 텀 프로젝트  (0) 2018.02.06
BOJ 14891 톱니바퀴  (0) 2018.02.05
BOJ 10451 순열 사이클  (0) 2018.01.30
BOJ 1707 이분 그래프  (0) 2018.01.29
BOJ 11724 연결 요소의 개수  (0) 2018.01.26

문제출처 : https://www.acmicpc.net/problem/10451


1. 문제요약

- 순열 사이클의 개수?


2. 접근방법

- 컴포넌트의 개수


3. 시간복잡도

- O(N)


4. 회고



소스코드 : dfs



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 14891 톱니바퀴  (0) 2018.02.05
BOJ 2331 반복수열  (0) 2018.01.30
BOJ 1707 이분 그래프  (0) 2018.01.29
BOJ 11724 연결 요소의 개수  (0) 2018.01.26
BOJ 1260 DFS와 BFS  (0) 2018.01.26

문제출처 : https://www.acmicpc.net/problem/1707


1. 문제요약

- 이분 그래프 인지 판별

- 1 <= V <= 20,000

- 1 <= E <= 200,000


2. 접근방법

- 한 정점을 방문했을 때 색깔(1, -1)을 칠해서 인접 정점들과 색이 다른지 확인

-    1(1)

      |

     2(-1)

   /     \

  3(1) ― 4(1)


- 이분 그래프 판별방법

  색이 칠해진 정점을 방문한 경우 현재 정점과 인접 정점의 색이 같다면 이분 그래프가 아님

                                                                            색이 다르다면 이분 그래프임


3. 시간복잡도

- O(VE) = 4,000,000,000


4. 회고

- 이분 그래프 판별방법 자체를 몰랐음...



소스코드 : bfs


소스코드 : dfs



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 2331 반복수열  (0) 2018.01.30
BOJ 10451 순열 사이클  (0) 2018.01.30
BOJ 11724 연결 요소의 개수  (0) 2018.01.26
BOJ 1260 DFS와 BFS  (0) 2018.01.26
BOJ 11052 붕어빵 판매하기  (0) 2018.01.25

문제출처 : https://www.acmicpc.net/problem/11724


1. 문제요약

- 컴포넌트의 갯수는?


2. 접근방법

- bfs, dfs


3. 시간복잡도

- O(VE)


4. 회고

- 다른사람보다 시간이 걸린이유는 입력속도의 차이라고 생각함



소스코드 : bfs


소스코드 : dfs



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 10451 순열 사이클  (0) 2018.01.30
BOJ 1707 이분 그래프  (0) 2018.01.29
BOJ 1260 DFS와 BFS  (0) 2018.01.26
BOJ 11052 붕어빵 판매하기  (0) 2018.01.25
BOJ 2011 암호코드  (0) 2018.01.25

문제출처 : https://www.acmicpc.net/problem/1260


1. 문제요약

- dfs와 bfs 방문순서

- dfs 방문순서 출력 후

  bfs 방문순서 출력


2. 접근방법

- dfs, bfs


3. 시간복잡도

- O(VE)


4. 회고

- 다른사람보다 시간이 걸린이유는

  1) 입력 시간

  2) 다른사람은 자료구조로 인접리스트를 썻고, 나는 인접행렬을 썼음

     난 출력이 순서대로 나와야 하기에 인접행렬을 인덱스로 검색하면 자동으로 순서가 되므로 인접행렬을 씀

     인접리스트를 쓴 다른사람들은 sort 함



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 1707 이분 그래프  (0) 2018.01.29
BOJ 11724 연결 요소의 개수  (0) 2018.01.26
BOJ 11052 붕어빵 판매하기  (0) 2018.01.25
BOJ 2011 암호코드  (0) 2018.01.25
BOJ 2225 합분해  (0) 2018.01.25

문제출처 : https://www.acmicpc.net/problem/11052


1. 문제요약

- 붕어 빵을 N개 팔아서 남는 최대 수익?

- 붕어빵을 i개 씩 묶어서 판매하는 가격은 Pi

- 붕어빵이 4개 남아있고, 1개 팔때 2 / 2개 팔때 5, 3개 팔때 6 / 4개 팔때 7인 경우

  붕어빵을 2개 2개 씩 팔면 10이 최대 수익


- 1 <= N <= 1,000

- 1 <= Pi <= 10,000


2. 접근방법

- 최대값은 최대값에서 찾는다.

- N 번째 붕어빵을 판매했을 때 최대 수익을 d[n]이라 하면

- N 번째 최대 수익은 이전까지 최대 수익(d[0] ~ d[n-1]) 중에 남은 붕어빵을 세트로 판매한 가격의 합의 최대

- 위의 예시를 따르자면
  d[1] = P1
  d[2] = 1 + 1 or 2 = d[1] + P1 or d[0] + P2
  d[3] = 1 + 1 + 1 or 1 + 2(2 + 1) or 3 = d[1] + P2(1 + 2) or d[2] + P1(1 + 1과 2 중의 큰값 + 1) or d[0] + P3(3)
  d[4] = 1 + 1 + 1 + 1 or 1 + 2 + 1(2 + 1 + 1, 1 + 1 + 2) or 1 + 3(3 + 1) or 4 = d[1] + P3 or d[2] + P2 or d[3] + P1 or d[0] + P4

- 즉, d[n] = max(d[0] + Pn, d[1] + Pn-1, d[2] + Pn-2, ... , d[n-1] + P1)


3. 시간복잡도

- 2 + 3 + ... + n = n(n+1)/2 = 약 500,000


4. 회고

- 생각해보면 굳이 d 배열을 쓸 필요없이 p 배열 하나면 되는 거였네



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 11724 연결 요소의 개수  (0) 2018.01.26
BOJ 1260 DFS와 BFS  (0) 2018.01.26
BOJ 2011 암호코드  (0) 2018.01.25
BOJ 2225 합분해  (0) 2018.01.25
BOJ 9461 파도반 수열  (0) 2018.01.24

문제출처 : https://www.acmicpc.net/problem/2011


1. 문제요약

- 알파벳 A ~ Z를 숫자 1 ~ 26에 대응 하여 암호를 만듦

- 25114 라는 암호를 만들었을 때, 해석 되는 가짓수는?

- 암호의 길이 N

- 1 <= N <= 5,000


2. 접근방법

- 길이가 n일 때, i 번째 숫자 까지 해석되는 경우의 수를 d[i]

- 최대 두 글자가 합쳐 질 수 있으므로

  d[i] = d[i-1] + d[i-2]


- 단, 0이 포함되어 있거나, 26을 넘어가는 숫자는 제외

- 01 인 경우, 숫자 0은 해석할 수 없으므로 d[1] = 0

- 10 인 경우, 숫자 1은 해석할 수 있으므로 d[1] = 1

                 숫자 0은 해석할 수 없으므로 1과 0은 따로 해석할 수 없고, 10은 해석 가능하므로 d[2] = 1

- 45 인 경우, 숫자 4, 5는 따로 해석 가능하지만, 45는 해석 할 수 없음. d[1] = 1, d[2] = 1


- 즉, 한 자릿수는 0 이외면 d[i] += d[i-1]

       두 자릿수는 10이상 26 이하면 d[i] += d[i-2]


3. 시간복잡도

- n


4. 회고

- 아에 생각을 잘못함...

-                   0 0 0 0 0

                   /           \

          0 | 0 0 0         0 0 | 0 0 0

- 이런식으로 나눠서 제일 마지막에 

  1개가 남고 0이 아니면 return 1

  2개가 남고 0이상 27 이하 이면 return 2

                 X0 인 경우 return 1

                 0X 인 경우 return 0

                 27 이상 return 0

- 이렇게 나눠서 생각했음

  너무 복잡하고 3333333 인경우 못골라냄...


- long long 은 약 18자릿수 까지 밖에 저장 못함...

- 5000 자릿수는 문자열로 받아야 함

  string 숫자를 int 숫자로 변환은 c[0] - '0'


- 넘 소스코드 좀 보자

- 난 n[i]와 d[i]의 인덱스를 같이 쓸려고 했는데

  같이 쓰면 d[1]일때 문자 2개의 경우의 수를 판단해야 되서 line 15와 같이 삽입했는데 그러지 말고

  d[n] : 길이 n번째 까지 만들 수 있는 암호의 수 라고 하면

  d[1]이 a[0]로 만들 수 있는 암호의 수가 되어서 line 15를 쓸 필요가 없었네



소스코드 : 맞은 소스


소스코드 : 틀린 소스



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 1260 DFS와 BFS  (0) 2018.01.26
BOJ 11052 붕어빵 판매하기  (0) 2018.01.25
BOJ 2225 합분해  (0) 2018.01.25
BOJ 9461 파도반 수열  (0) 2018.01.24
BOJ 1966 제곱수의 합  (0) 2018.01.23

문제출처 : https://www.acmicpc.net/problem/2225


1. 문제요약

- 0 부터 N까지의 정수 K개를 더해서 그 합이 N이 되는 경우의 수

- 1 + 2와 2 + 1은 다른 경우

- 숫자는 중복해서 사용 가능

- 1 <= N <= 200

- 1 <= K <= 200


2. 접근방법

- 숫자 N은 N-0 + 0

               N-1 + 1

               N-2 + 2

               N-3 + 3

               ...

               N-N + N

  으로 만들 수 있음

- d[n][k] : K번째 합이 N인 경우의 수라 하면


- d[n][k] = d[n-0][k-1] + d[n-1][k-1] + d[n-2][k-1] + ... + d[n-n][k-1]


3. 시간복잡도

- O(KN^2) = 8,000,000


4. 회고

- 합산 결과가 int를 넘는가?

- 재귀 리턴값이 옳바른가?


- mod 연산 할때

- <소스 2> 처럼 했었는데 틀리고 <소스 1>은 맞음

- <소스 2> : d[sum][cnt] = (A mod div + B mod div + ... N mod div) mod div 가 들어가고

  <소스 1> : d[sum][cnt] = (A mod div + B mod div + ... N mod div) mod div 가 들어가는데?


- 어라 근데 return d[sum][cnt] %= div 인데.. 연산자 우선순위 때문인가? 괄호 안쳐서 그런가?

  해봐야겠다


- <소스 1>은 맞고 <소스 2>가 틀린 이유는 '메모이제이션' 때문....

- <소스 1>의 d 배열에는 나머지 값이 들어가 있어서 line 6에서 정상적으로 나머지값이 반환됨.

- <소스 2>의 d 배열에는 나머지 값이 들어가 있지 않아서 line 6에서 나머지 연산 전의 값이 반환됨.

  <소스 2>의 line 6를 return d[sum][cnt] % div로 바꿔주면 정답


- <소스 2>의 line 11을 return d[sum][cnt] %= div로 바꿔주면 제일 빨리 수행됨

  나머지 연산이 덧셈 때 마다들어가지 않기 때문에


- 예를 들어 div = 5일 때,

  1 1 1   1 1 1   1 1 1

    3         3        3

              9 // <소스 1>은 9div5 = 4가 저장되고 / <소스 2>는 9가 저장됨

              ...

              12 // <소스 1>과 <소스 2> 모두 합은 4 + 4 + 4 이지만

                     <소스 1>은 12div5 = 2가 <소스 2>는 12가 저장됨

                      메모이제이션할때 저장된 값을 리턴하면

                     <소스 1>은 2를 <소스 2> 는 12를 리턴하므로 틀린 값이 나옴

                     그래서 <소스 2>의 line 6를 return d[sum][cnt] % div로 바꿔주면 정답이 됨.

long long dp(int sum, int cnt){
	if (cnt == 1)
		return 1;

	if (d[sum][cnt])
		return d[sum][cnt];

	for (int i = 0; i <= sum; i++){
		d[sum][cnt] += dp(sum - i, cnt - 1);
		d[sum][cnt] %= 1000000000;
	}

	return d[sum][cnt];
}

<소스 1>


long long dp(int sum, int cnt){
	if (cnt == 1)
		return 1;

	if (d[sum][cnt])
		return d[sum][cnt];

	for (int i = 0; i <= sum; i++)
		d[sum][cnt] += dp(sum - i, cnt - 1);

	return d[sum][cnt] % 1000000000;
}

<소스 2>



소스코드 : Top-Down


소스코드 : Bottom-Up



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 11052 붕어빵 판매하기  (0) 2018.01.25
BOJ 2011 암호코드  (0) 2018.01.25
BOJ 9461 파도반 수열  (0) 2018.01.24
BOJ 1966 제곱수의 합  (0) 2018.01.23
BOJ 2579 계단 오르기  (0) 2018.01.22

문제출처 : https://www.acmicpc.net/problem/9461


1. 문제요약

- 아래 그림처럼 정삼각형을 이어붙임

- 해당 나선 그림에서 가장 긴 변의 길이를 k라 했을 떄, 그 변에 길이가 k인 정삼각형을 추가

- 파도반 수열 p[n]은 나선에 있는 정삼각형의 한 변의 길이

  p[1] ~ p[10]까지 1, 1, 1, 2, 2, 3, 4, 5, 7, 9

- 1 <= n <= 100일때 p[n]의 값은?

2. 접근방법

- 수열의 규칙 찾기

- p[n] = p[n-1] + p[n-5]


3. 시간복잡도

- n


4. 회고

- p[n]의 값이 int 범위를 넘어감.

- 가장 작은 입력, 가장 큰 입력에 대해 테스트 필요함



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 2011 암호코드  (0) 2018.01.25
BOJ 2225 합분해  (0) 2018.01.25
BOJ 1966 제곱수의 합  (0) 2018.01.23
BOJ 2579 계단 오르기  (0) 2018.01.22
BOJ 1912 연속합  (0) 2018.01.21

문제출처 : https://www.acmicpc.net/problem/1699


1. 문제요약

- 어떤 자연수 N은 그보다 작거나 같은 제곱수들의 합으로 나타낼 수 있음

- 11 = 3^2 + 1^2 + 1^2(3개항)

  11 = 2^2 + 2^2 + 1^2 + 1^2 + 1^2(5개항)

- 11의 최소 제곱수 항의 갯수는 3개

- 자연수 N의 최소 제곱수 항의 갯수는?

- 1 <= N <= 100,000


2. 접근방법

- 임의의 정수 N에서

  1^2을 빼면 N-1

  2^2을 빼면 N-4

  ...

- d[n] 을 n의 최소 제곱수 갯수 라고 하면

  d[n] = min(d[0] + 1, d[1] + 1, d[2] + 1, d[3] + 1 ..., d[i <= j * j] + 1)


3. 시간복잡도

- 1 ~ 3 : 1 = 3

  4 ~ 8 : 2 = 2 * 5

  9 ~ 16 : 3 = 3 * 7

  17 ~ 25 : 4 = 4 * 9

  ...

- ∑(k = 1, 300)(2k + 1) * k = 2∑(k = 1, 300)k^2 + ∑(k = 1, 300)k


4. 회고

- 처음에 무조건 임의의 자연수 n에 가까운 제곱수를 구하면 되는 줄 알았는데

- 12 = 3^2 + 1^2 + 1^2 + 1^2 = 4개항

  12 = 2^2 + 2^2 + 2^2 = 3개항


※ 근데 맞은 소스랑 틀린 소스랑 차이가 없는데 왜 맞고 틀리지??????

채점 서버 문제였음..



소스코드 : 맞은 소스



소스 코드 : 틀린 소스 맞음



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 2225 합분해  (0) 2018.01.25
BOJ 9461 파도반 수열  (0) 2018.01.24
BOJ 2579 계단 오르기  (0) 2018.01.22
BOJ 1912 연속합  (0) 2018.01.21
BOJ 11054 가장 긴 바이토닉 부분 수열  (0) 2018.01.20

+ Recent posts