일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- SWEA
- BFS
- PS
- sw expert academy
- 맛집
- 다이나믹 프로그래밍
- 백준
- 완전탐색
- 에라토스테네스의 체
- 잠실
- 시뮬레이션
- koitp
- DP
- 알고리즘
- 삼성 SDS 대학생 알고리즘 특강
- C++
- dfs
- 동적 계획법
- BOJ
- dynamic programming
- Algorithm
- 구현
- 해커랭크
- 삼성 기출
- 스택
- 백트래킹
- 그리디
- 소수
- 브루트포스
- hackerrank
- Today
- Total
펭로그
[C++] 백준 BOJ 6359 만취한 상범 본문
문제링크 : https://boj.kr/6359
DP 문제라고 한다.
왜 DP 문제인지는 잘 모르겠지만 DP로 풀지 않으면 정말 쉽게 풀린다.
N이 5라고 가정하고 시뮬레이션을 해보자.
0은 문이 닫힌 상태를 1은 문이 열린 상태를 의미한다.
맨 처음
0 0 0 0 0
1라운드
1 1 1 1 1
2라운드
1 0 1 0 1
3라운드
1 0 0 0 1
4라운드
1 0 0 1 1
5라운드
1 0 0 1 0
이쯤 하면 규칙을 찾을 수 있다.
각 라운드에 해당하는 숫자만큼의 배수를 찾아서 1 → 0 / 0 → 1 으로 바꿔주면 된다.
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 | // BOJ 6359 만취한 상범 #include <iostream> #include <vector> using namespace std; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int tc, num; cin >> tc; while (tc--) { cin >> num; vector<bool> prison(num + 1, false); for(int i = 1; i <= num; i++) for(int j = i; j <= num; j += i) prison[j] = !prison[j]; int result = 0; for(int i = 1; i <= num; i++) result += prison[i]; cout << result << '\n'; } return 0; } | cs |
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 | // BOJ 6359 만취한 상범 #include <iostream> using namespace std; bool prison[101]; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int tc, num; cin >> tc; for(int i = 1; i <= 100; i++) for(int j = i; j <= 100; j += i) prison[j] = !prison[j]; while (tc--) { cin >> num; int result = 0; for(int i = 1; i <= num; i++) result += prison[i]; cout << result << '\n'; } return 0; } | cs |
1 - 1 1 1 1 1 1 1 1 1 1
2 - 1 0 1 0 1 0 1 0 1 0
3 - 1 0 0 0 1 1 1 0 0 0
4 - 1 0 0 1 1 1 1 1 0 0
5 - 1 0 0 1 0 1 1 1 0 1
6 - 1 0 0 1 0 0 1 1 0 1
7 - 1 0 0 1 0 0 0 1 0 1
8 - 1 0 0 1 0 0 0 0 0 1
9 - 1 0 0 1 0 0 0 0 1 1
10- 1 0 0 1 0 0 0 0 1 0
만취한 상범이의 미친 짓을 수행할 때 마다 문이 열리고 닫히는 것은 계속 수행하다보면
전 라운드의 값을 메모이제이션 할 수 있는 것을 알 수 있다.
이를 토대로 DP로 풀면 된다.
하지만, 또 다른 규칙을 발견할 수 있는데..
N라운드 시행 이후 문이 열려있는 감옥은 우연히도 제곱수인 것을 확인할 수 있다...!
0 - 1 2 3 4 5 6 7 8 9 10
1 - 1 1 1 1 1 1 1 1 1 1
2 - 1 0 1 0 1 0 1 0 1 0
3 - 1 0 0 0 1 1 1 0 0 0
4 - 1 0 0 1 1 1 1 1 0 0
5 - 1 0 0 1 0 1 1 1 0 1
6 - 1 0 0 1 0 0 1 1 0 1
7 - 1 0 0 1 0 0 0 1 0 1
8 - 1 0 0 1 0 0 0 0 0 1
9 - 1 0 0 1 0 0 0 0 1 1
10- 1 0 0 1 0 0 0 0 1 0
결론은.. N보다 작은 제곱수가 몇개인지만 구하면 된다.
N을 루트 씌우고 소수점을 떼면... 답이 나온다.
DP로 풀어도 되지만 DP로 푸는 것보다 훨씬 간단하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // BOJ 6359 만취한 상범 #include <iostream> #include <cmath> using namespace std; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int tc, num; cin >> tc; while (tc--) { cin >> num; cout << int(sqrt(num)) << '\n'; } return 0; } | cs |
'Study > PS(Algorithm)' 카테고리의 다른 글
[C++] 백준 BOJ 3048 개미 (0) | 2018.09.21 |
---|---|
[C++] 백준 BOJ 11559 Puyo Puyo (0) | 2018.09.20 |
[C++] 백준 BOJ 1010 다리 놓기 (0) | 2018.09.19 |
[C++] 백준 BOJ 1929 소수 구하기 (0) | 2018.09.19 |
[C++] 백준 BOJ 3055 탈출 (0) | 2018.09.18 |