일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- CS Academy
- Eulerian circuit
- bitmask
- POJ
- flows
- BOJ
- mathematics
- BST
- Sieve_of_Eratosthenes
- graph modeling
- backtracking
- implementation
- disjoint-set
- Eulerian path
- GCD
- Euler path
- Greedy
- Cycle detecting
- 백준
- Segment Tree
- DynamicProgramming
- hashing
- dynamic programming
- Euler circuit
- Shortest path
- BFSDFS
- Dag
- graph
- scc
- Algospot
- Today
- Total
그냥 하는 노트와 메모장
Codeforces Round #459 (Div. 2) 본문
A. Eleven
주어진 길이에 대해 피보나치 수가 넘어가지 않을 때까지 'O'로 바꿔주기만 하면 된다.
#include <cstdio> #include <cstring> int main() { int N,a=1,b=1,t; char name[1001] = {}; scanf("%d", &N); memset(name, 'o', N); name[0] = 'O'; while (a + b <= N) { name[a + b - 1] = 'O'; t = b; b = a + b; a = t; } printf("%s", name); return 0; }
B. Radio Station
map 등의 hashing 자료구조를 활용하여 해결할 수 있다. 문자열 통째로 key로 두던가 아니면 필자처럼 숫자로 변경해서 해싱을 진행해도 좋다.
#include <cstdio> #include <map> using namespace std; using ll = long long; int main() { map<ll, char*> pool; ll ip; int n, m, a, b, c, d; char *tmp,name[11]; scanf("%d%d\n", &n, &m); while (n--) { ip = 0; tmp = new char[11]{}; scanf("%s %d.%d.%d.%d\n", tmp, &a, &b, &c, &d); ip |= a; ip <<= 8; ip |= b; ip <<= 8; ip |= c; ip <<= 8; ip |= d; pool[ip] = tmp; } while (m--) { scanf("%s %d.%d.%d.%d;\n", name, &a, &b, &c, &d); ip = 0; ip |= a; ip <<= 8; ip |= b; ip <<= 8; ip |= c; ip <<= 8; ip |= d; printf("%s %d.%d.%d.%d; #%s\n", name, a, b, c, d, pool[ip]); } return 0; }
C. The Monster
두 가지 포인트에 집중한다.
1. 구간 (l,r)은 최대 길이 5000에 대해서 5000*(5001)/2 개의 조합이 나올 수 있다.
2. 구간 (l,r)에 대해 l을 고정한 것에 대해 l<r<L(문자열 s의 길이) 에 대해 (l,r)을 계산할 때 (l,r-1)을 이용할 수 있다(optimal substructure)
1.에 의해 O(N^2) 솔루션이 가능하고, 2.에 의해 이중 for문 안에서 이전에 있던 위치값을 이용할 수 있음을 알 수 있다.
+) 대부분 이런식으로 푼 것 같다. 구간에 대해 올바른 순서가 존재할 수 있는지만을 판단한다.
1. left, right 구간을 줄 변수를 둔다. 구간 (i,j)에 대해 가상 left, right를 각각 l,r로 둔다. i부터 j까지 correct bracket sequence를 만족하면 l = 0이 된다. 반면 r이 음수일 경우 ')'로 시작하는 것이기에 이 때는 i로 시작하는 올바른 순서가 존재할 수 없다. r의 역할은 ?의 개수 및 (의 개수를 말한다. l의 역할은 현재 (인지와 ?가 (인지를 말한다.
2. 가상 구간에 대해 문자에 따라 처리해준다.
2-1. (일 경우 : l++, r++
2-2. )일 경우 : l--, r--
2-3. ?일 경우 : l--, r++
자세한 내용은 에디토리얼에 나와 있다.
#include <cstdio> #include <cstring> int main() { char board[5001]; int i, j,L,ans = 0,l,r; scanf("%s", board); L = strlen(board); for (i = 0; i < L; i++) { l = r = 0; for (j = i; j < L; j++) { if (board[j] == '(') l++, r++; else if (board[j] == ')') l--, r--; else l--, r++; if (r < 0) break; if (l < 0) l = 1; if (l == 0) ans++; } } printf("%d", ans); return 0; }
D. MADMAX
제목처럼 서로 각 턴에 대해 많은 정점을 방문하면 이길 수 있게 되어 있다.
또한 각 턴마다 상대방이 지난 간선 보다 ASCII Code 상 크거나 같은 값을 지닌 간선만 지나갈 수 있다. 본문에 쓰여있듯 경우의 수가 매우 많기 때문에 브루트 포스로 처리하기엔 너무 오래 걸린다. 또한 A(Max)와 B(Lucas)의 상태도를 나타면 100x100의 경우가 있으며 이전상태에 대해 소문자 알파벳의 총 수 26 가지가 존재하게 된다. 추가적으로 처음 게임을 시작할 때는 어떤 간선을 갈 수 있도록 설정해야하므로 1을 추가해준다. 따라서 명백하게 부분문제가 겹치는 것을 알 수 있으므로 dynamic programming을 진행한다.
cache[이전 알파벳][현재 A의 정점 위치][현재 B의 정점 위치]
시간 복잡도 : O(N^2)
#include <cstdio> #include <vector> #include <cstring> using namespace std; vector<vector<int>> adj; int cache[27][100][100], board[100][100]; // NONE : 0, 'a' : 1 bool dfs(int bef, int vn, int rn) { int& ret = cache[bef][vn][rn]; if (ret == -1) { ret = 0; for (int v : adj[rn]) if (bef <= board[rn][v]) if(!dfs(board[rn][v], v, vn)) ret = 1; } return ret; } int main() { memset(cache, -1, sizeof(cache)); char ch; int n, m,u,v,A,B,i,j; scanf("%d%d", &n, &m); adj.resize(n); while (m--) { scanf("%d%d %c\n", &u, &v, &ch); u--, v--; adj[u].push_back(v); board[u][v] = ch - 'a' + 1; } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) printf("%c", dfs(0, j, i) ? 'A' : 'B'); puts(""); } return 0; }
E. Pollywog
'Contest, Other tests' 카테고리의 다른 글
Codeforces Round #462 (Div. 2) (0) | 2018.02.19 |
---|---|
제1회 천하제일 코딩대회 본선 (해설 미완성) (0) | 2018.02.04 |
Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) (0) | 2018.01.23 |
제 12회 총장배 서강대학교 프로그래밍 대회 Champion (Ongoing) (0) | 2018.01.19 |
제 12회 총장배 서강대학교 프로그래밍 대회 Master (Ongoing) (0) | 2018.01.19 |