[RUNNINGMEDIAN] 변화하는 중간 값
[RUNNINGMEDIAN] 변화하는 중간 값 : https://algospot.com/judge/problem/read/RUNNINGMEDIAN
### 우선순위 큐 (힙) ###
<소스코드>
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 34 35 36 37 38 39 40 41 | #include <cstdio> #include <vector> #include <queue> using namespace std; typedef long long int lli; const lli MOD = 20090711LL; int main() { int tc; scanf("%d", &tc); while(tc--) { int n, b; lli a; scanf("%d%lld%d", &n, &a, &b); lli ai = 1983LL; lli ans = ai; priority_queue<lli> minH, maxH; maxH.push(ai); for(int i=1; i<n; i++) { ai = (1LL*ai*a+b)%MOD; if(i&1) minH.push(-ai); else maxH.push(ai); if(-minH.top() < maxH.top()) { int a = maxH.top(); maxH.pop(); int b = -minH.top(); minH.pop(); maxH.push(b); minH.push(-a); } ans = (ans + maxH.top()) % MOD; } printf("%lld\n", ans); } return 0; } | cs |
>> 맥스힙에는 중간값 기준으로 중간값 포함, 그보다 작은 것들을, 민힙에는 중간값보다 큰 녀석들이 들어가게 된다.
'PS > 종만북' 카테고리의 다른 글
[DICTIONARY] 고대어 사전 (0) | 2018.05.22 |
---|---|
[BOGGLE] 보글게임 (0) | 2018.04.30 |
[MATCHORDER] 출전 순서 정하기 (0) | 2018.04.20 |
[NUMBERGAME] 숫자게임 (0) | 2018.04.17 |
[POLY] 폴리오미노 (0) | 2018.04.16 |
[DICTIONARY] 고대어 사전
[DICTIONARY] 고대어 사전 : https://algospot.com/judge/problem/read/DICTIONARY
### 위상정렬 ###
<소스코드>
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | #include <cstdio> #include <iostream> #include <string> #include <vector> #include <queue> using namespace std; int main() { int tc; scanf("%d", &tc); while(tc--) { int n; scanf("%d", &n); vector<string> v; for(int i=0; i<n; i++) { string s; cin >> s; v.push_back(s); } int ind[26]={0}; vector<int> g[26]; for(int i=1; i<n; i++) { int idx=0; while(v[i-1][idx] != 0 && v[i][idx] != 0) { if(v[i-1][idx] == v[i][idx]) idx++; else break; } if(v[i-1][idx] != 0 && v[i][idx] != 0) { g[v[i-1][idx]-'a'].push_back(v[i][idx]-'a'); ind[v[i][idx]-'a']++; } } queue<int> q; for(int i=0; i<26; i++) { if(!ind[i]) q.push(i); } vector<char> ans; while(!q.empty()) { int cur = q.front(); q.pop(); ans.push_back('a'+cur); for(int i=0; i<g[cur].size(); i++) { int next = g[cur][i]; ind[next]--; if(!ind[next]) { q.push(next); } } } if(ans.size() != 26) puts("INVALID HYPOTHESIS"); else { for(int i=0; i<ans.size(); i++) printf("%c", ans[i]); puts(""); } } return 0; } | cs |
<예전에 AC 받은 코드> - 코드를 보면 종만북 솔루션으로 있는 코드같아 보인다.
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | #include <cstdio> #include <iostream> #include <vector> #include <algorithm> using namespace std; vector<int> order; vector<bool> visited; vector<vector<int> > v; void makeGraph(const vector<string> &words) { v = vector<vector<int> >(26, vector<int>(26, 0)); for(int i=1; i<words.size(); i++) { int len = min(words[i-1].size(), words[i].size()); for(int k=0; k<len; k++) { int a = words[i-1][k]-'a'; int b = words[i][k]-'a'; if(a != b) { v[a][b] = 1; break; } } } } void dfs(int s) { visited[s] = 1; for(int i=0; i<v.size(); i++) if(v[s][i] && !visited[i]) dfs(i); order.push_back(s); } vector<int> topologicalSort() { int i, j, n=v.size(); visited = vector<bool>(n, 0); order.clear(); for(i=0; i<n; i++) if(!visited[i]) dfs(i); reverse(order.begin(), order.end()); for(i=0; i<n; i++) for(j=i+1; j<n; j++) if(v[order[j]][order[i]]) return vector<int>(); return order; } int main() { int tc; scanf("%d", &tc); while(tc--) { int n; vector<string> words; scanf("%d", &n); while(n--) { string s; cin >> s; words.push_back(s); } makeGraph(words); vector<int> ans = topologicalSort(); n = ans.size(); if(!n) puts("INVALID HYPOTHESIS"); else { for(int i=0; i<n; i++) { printf("%c", ans[i]+'a'); } puts(""); } } } | cs |
'PS > 종만북' 카테고리의 다른 글
[RUNNINGMEDIAN] 변화하는 중간 값 (0) | 2018.07.20 |
---|---|
[BOGGLE] 보글게임 (0) | 2018.04.30 |
[MATCHORDER] 출전 순서 정하기 (0) | 2018.04.20 |
[NUMBERGAME] 숫자게임 (0) | 2018.04.17 |
[POLY] 폴리오미노 (0) | 2018.04.16 |
[BOGGLE] 보글게임
[BOGGLE] 보글 게임 : https://algospot.com/judge/problem/read/BOGGLE?c=16921
### DP ###
check(i, j, word) : (i, j) 에서 문자열 word 를 만들수 있는지.
<소스코드>
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #include <cstdio> #include <cstring> #include <string> #include <map> using namespace std; char boggle[5][6]; int di[]={1, 1, 0, -1, -1, -1, 0, 1}; int dj[]={0, 1, 1, 1, 0, -1, -1, -1}; int sNum = 1; map<string, int> msi; int d[5][5][10000]; int check(int curI, int curJ, char *word) { if(*(word+1) == 0) return true; int num; if(msi.find(word) == msi.end()) { msi[word] = sNum; num = sNum++; } else num = msi[word]; int &ret = d[curI][curJ][num]; if(ret != 0) return ret; for(int k=0; k<8; k++) { int nextI = curI+di[k]; int nextJ = curJ+dj[k]; if((0 <= nextI && nextI < 5) && (0 <= nextJ && nextJ < 5)) { if(boggle[nextI][nextJ] == *(word+1) && check(nextI, nextJ, word+1) == 1) return ret = 1; } } return ret = -1; } bool BOGGLE(char *word) { for(int i=0; i<5; i++) for(int j=0; j<5; j++) if(boggle[i][j] == *word && check(i, j, word) == 1) return true; return false; } int main() { int tc; scanf("%d", &tc); while(tc--) { for(int i=0; i<5; i++) scanf("%s", boggle[i]); memset(d, 0, sizeof(d)); int n; scanf("%d", &n); while(n--) { char word[11]; scanf("%s", word); printf("%s ", word); BOGGLE(word) ? puts("YES") : puts("NO"); } } } | cs |
>> 완전 탐색으로 소개되는 문제지만, 시간초과가 난다.
>> 해결방법은 DP 라는데...
>> 문자열을 메모이제이션 할 방법이 도무지 떠오르질 않아 푸는데 오래 걸렸던 문제..!! >> 해싱으로 처리하였다.
'PS > 종만북' 카테고리의 다른 글
[RUNNINGMEDIAN] 변화하는 중간 값 (0) | 2018.07.20 |
---|---|
[DICTIONARY] 고대어 사전 (0) | 2018.05.22 |
[MATCHORDER] 출전 순서 정하기 (0) | 2018.04.20 |
[NUMBERGAME] 숫자게임 (0) | 2018.04.17 |
[POLY] 폴리오미노 (0) | 2018.04.16 |
[MATCHORDER] 출전 순서 정하기
[MATCHORDER] 출전 순서 정하기 : https://algospot.com/judge/problem/read/MATCHORDER
### Greedy ###
< 소스코드 >
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 34 35 36 | #include <cstdio> #include <algorithm> using namespace std; int Rus[101], Kor[101]; int main() { int tc; scanf("%d", &tc); while(tc--) { int n; scanf("%d", &n); for(int i=0; i<n; i++) scanf("%d", Rus+i); for(int i=0; i<n; i++) scanf("%d", Kor+i); sort(Rus, Rus+n); sort(Kor, Kor+n); int ri=0, ki=0; int ans=0; while(ri < n && ki < n) { if(Rus[ri] <= Kor[ki]) { ans++; ri++; ki++; } else ki++; } printf("%d\n", ans); } } | cs |
>> 차이가 최소가 되도록, 각각 오름차순 정렬 후 Korea 가 같거나 크면 이기고,
>> 러시아가 크면 다음으로 큰 한국 점수가 나올때까지 인덱스를 증가시킨다.
'PS > 종만북' 카테고리의 다른 글
[DICTIONARY] 고대어 사전 (0) | 2018.05.22 |
---|---|
[BOGGLE] 보글게임 (0) | 2018.04.30 |
[NUMBERGAME] 숫자게임 (0) | 2018.04.17 |
[POLY] 폴리오미노 (0) | 2018.04.16 |
[ASYMTILING] 비대칭 타일링 (0) | 2018.04.16 |
[NUMBERGAME] 숫자게임
[NUMBERGAME] 숫자게임 : https://algospot.com/judge/problem/read/NUMBERGAME
< 소스코드 >
gameNum(s, e) : (s, e) 까지 최선을 다해 게임을 했을 때, 서하점수-현우점수의 최대값.
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #include <stdio.h> #include <string.h> const int INF = 1e9; int a[51]; int d[51][51]; int max(int a, int b) { return a > b ? a : b; } int gameNum(int s, int e) { int ret=0; if(s == e) return a[s]; if(s > e) return 0; if(d[s][e] != INF) return d[s][e]; ret = max(a[s]-gameNum(s+1, e), a[e]-gameNum(s, e-1)); if(e-s >= 1) ret = max(ret, -gameNum(s+2, e)); if(e-s >= 1) ret = max(ret, -gameNum(s, e-2)); return d[s][e] = ret; } int main() { int tc; scanf("%d", &tc); while(tc--) { int n; scanf("%d", &n); for(int i=0; i<n; i++) { scanf("%d", a+i); for(int j=0; j<n; j++) d[i][j] = INF; } printf("%d\n", gameNum(0, n-1)); } return 0; } | cs |
>> 재귀적으로 함수를 호출하는 과정에서 음수처리 한 부분에 주목.
>> 현우부터 게임을 시작하고, 현우가 서하보다 몇점을 더 얻을수 있는지 알아야 하기에..
>> 첫번째 턴에서 현우가 가진 점수는 그대로 현우의 점수가 된다. 두번째 턴에서 서하가 가진 점수는 현우의 점수에서 빼주면 그것이 그대로 차이가 된다.
'PS > 종만북' 카테고리의 다른 글
[BOGGLE] 보글게임 (0) | 2018.04.30 |
---|---|
[MATCHORDER] 출전 순서 정하기 (0) | 2018.04.20 |
[POLY] 폴리오미노 (0) | 2018.04.16 |
[ASYMTILING] 비대칭 타일링 (0) | 2018.04.16 |
[TRIPATHCNT] 삼각형 위의 최대 경로 수 세기 (0) | 2018.04.15 |
[POLY] 폴리오미노
[POLY] 폴리오미노 : https://algospot.com/judge/problem/read/POLY
### DP ###
< 소스코드 >
poly(up, n) : 윗층에 up개의 블럭이 쌓여있을 때, n 개로 폴리오미노를 만들 수 있는 방법의 수.
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 34 35 36 37 38 | #include <stdio.h> const int MOD = 10000000; int d[101][101]; int poly(int up, int n) { int ret = 0; if(n == 0) return 1; if(n == 1) return up; if(d[up][n]) return d[up][n]; for(int down=1; down<=n; down++) { ret += (poly(down, n-down)*(up+down-1)); ret %= MOD; } return d[up][n] = ret; } int main() { int tc; scanf("%d", &tc); while(tc--) { int n, ans=0; scanf("%d", &n); for(int i=1; i<=n; i++) { ans += poly(i, n-i); ans %= MOD; } printf("%d\n", ans); } return 0; } | cs |
>> 15 : 곱해줘야하는데, 더해서 시간을 많이 소비했다....
'PS > 종만북' 카테고리의 다른 글
[MATCHORDER] 출전 순서 정하기 (0) | 2018.04.20 |
---|---|
[NUMBERGAME] 숫자게임 (0) | 2018.04.17 |
[ASYMTILING] 비대칭 타일링 (0) | 2018.04.16 |
[TRIPATHCNT] 삼각형 위의 최대 경로 수 세기 (0) | 2018.04.15 |
[TILING2] 타일링 (0) | 2018.04.15 |
[ASYMTILING] 비대칭 타일링
[ASYMTILING] 비대칭 타일링 : https://algospot.com/judge/problem/read/ASYMTILING
### DP ###
< 소스코드 >
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 34 | #include <stdio.h> const int MOD = 1000000007; int d[101]; int tiling(int n) { if(n <= 1) return 1; if(d[n]) return d[n]; return d[n] = (tiling(n-1) + tiling(n-2)) % MOD; } int asymtiling(int n) { int ret; ret = tiling(n/2) % MOD; if(n&1) return ret; ret += ((tiling((n/2)-1)) % MOD); return ret%MOD; } int main() { int tc; scanf("%d", &tc); while(tc--) { int n; scanf("%d", &n); printf("%d\n", (tiling(n)-asymtiling(n)+MOD)%MOD); } return 0; } | cs |
>> 전체 경우의 수에서 대칭적으로 만들수 있는 타일링의 갯수를 빼면 된다.
'PS > 종만북' 카테고리의 다른 글
[NUMBERGAME] 숫자게임 (0) | 2018.04.17 |
---|---|
[POLY] 폴리오미노 (0) | 2018.04.16 |
[TRIPATHCNT] 삼각형 위의 최대 경로 수 세기 (0) | 2018.04.15 |
[TILING2] 타일링 (0) | 2018.04.15 |
[PI] 원주율 외우기 (0) | 2018.04.15 |
[TRIPATHCNT] 삼각형 위의 최대 경로 수 세기
[TRIPATHCNT] 삼각형 위의 최대 경로 수 세기 : https://algospot.com/judge/problem/read/TRIPATHCNT
### DP ###
< 소스코드 >
PathCnt(r, c) : (r, c) 좌표에서 시작하는 삼각형 위의 최대 경로 후.
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #include <stdio.h> #include <string.h> int n; int a[101][101]; int d[101][101], e[101][101]; int max(int a, int b) { return a > b ? a : b; } int PathSum(int r, int c) { int ret; if(!a[r][c]) return 0; if(r == n) return a[r][c]; if(e[r][c]) return e[r][c]; ret = max(PathSum(r+1, c), PathSum(r+1, c+1)); return e[r][c] = ret + a[r][c]; } int PathCnt(int r, int c) { int ret=0; int a, b; if(r == n) return 1; if(d[r][c]) return d[r][c]; a = PathSum(r+1, c); b = PathSum(r+1, c+1); if(a == b) ret += (PathCnt(r+1, c) + PathCnt(r+1, c+1)); else ret += (a > b ? PathCnt(r+1, c) : PathCnt(r+1, c+1)); return d[r][c] = ret; } int main() { int tc; scanf("%d", &tc); while(tc--) { scanf("%d", &n); for(int i=1; i<=n; i++) for(int j=1; j<=i; j++) scanf("%d", &a[i][j]); memset(d, 0, sizeof(d)); memset(e, 0, sizeof(e)); printf("%d\n", PathCnt(1, 1)); } return 0; } | cs |
>> 일단 삼각형 위의 최대값을 구한 다음에 갯수를 세야한다.
>> 다음으로 위치에서 시작하는 삼각형위의 최대값이 최대일 때, 갯수에 포함시켜야 한다. 같다면 둘다 포함시킨다.
'PS > 종만북' 카테고리의 다른 글
[POLY] 폴리오미노 (0) | 2018.04.16 |
---|---|
[ASYMTILING] 비대칭 타일링 (0) | 2018.04.16 |
[TILING2] 타일링 (0) | 2018.04.15 |
[PI] 원주율 외우기 (0) | 2018.04.15 |
[LIS] 최대 증가 부분 수열 (0) | 2018.04.13 |
[TILING2] 타일링
[TILING2] 타일링 : https://algospot.com/judge/problem/read/TILING2
< 소스코드 >
tiling(n) : 2 x n 크기의 사각형을 2 x 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 | #include <stdio.h> #define MOD 1000000007 int d[101]; int tiling2(int n) { if(n == 0) return 1; if(n < 0) return 0; if(d[n]) return d[n]; return d[n] = (tiling2(n-1) + tiling2(n-2)) % MOD; } int main() { int tc; scanf("%d", &tc); while(tc--) { int n; scanf("%d", &n); printf("%d\n", tiling2(n)); } return 0; } | cs |
>> 2 x 1 하나를 채우고 나면 2 x n-1 크기를 채우면 된다.
>> 1 x 2 두개를 = 이렇게 채우고 나면, 2 x n-2 크기를 채우면 된다.
'PS > 종만북' 카테고리의 다른 글
[ASYMTILING] 비대칭 타일링 (0) | 2018.04.16 |
---|---|
[TRIPATHCNT] 삼각형 위의 최대 경로 수 세기 (0) | 2018.04.15 |
[PI] 원주율 외우기 (0) | 2018.04.15 |
[LIS] 최대 증가 부분 수열 (0) | 2018.04.13 |
[TRIANGLEPATH] 삼각형 위의 최대경로 (0) | 2018.04.10 |
[PI] 원주율 외우기
[PI] 원주율 외우기 : https://algospot.com/judge/problem/read/PI
### DP ###
< 소스코드 >
pi(i) : i 번째 인덱스에서 시작하는 난이도의 최소 합.
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | #include <stdio.h> #include <string.h> #define INF 1e9 char p[10001]; int len, d[10001]; int min(int a, int b) { return a < b ? a : b; } int isSame(int s, int cnt) { for(int i=s; i<s+cnt-1; i++) if(p[i] != p[i+1]) return 0; return 1; } int isInc(int s, int cnt) { for(int i=s; i<s+cnt-1; i++) if(p[i]+1 != p[i+1]) return 0; return 1; } int isDec(int s, int cnt) { for(int i=s; i<s+cnt-1; i++) if(p[i]-1 != p[i+1]) return 0; return 1; } int isAlter(int s, int cnt) { if(cnt == 3) { if(p[s] == p[s+2]) return 1; } else if(cnt == 4) { if(p[s] == p[s+2] && p[s+1] == p[s+3]) return 1; } else if(cnt == 5) { if(p[s] == p[s+2] && p[s+2] == p[s+4] && p[s+1] == p[s+3]) return 1; } return 0; } int isSeq(int s, int cnt) { int diff = p[s+1] - p[s]; for(int i=s; i<s+cnt-1; i++) if(p[i]+diff != p[i+1]) return 0; return 1; } int getScore(int s, int cnt) { if(isSame(s, cnt)) return 1; if(isInc(s, cnt) || isDec(s, cnt)) return 2; if(isAlter(s, cnt)) return 4; if(isSeq(s, cnt)) return 5; return 10; } int pi(int s) { int k, ret = INF; if(s == len) return 0; if(s > len) return INF; if(d[s]) return d[s]; for(int i=3; i<=5; i++) { k = getScore(s, i); ret = min(ret, pi(s+i)+k); } return d[s] = ret; } int main() { int tc; scanf("%d", &tc); while(tc--) { scanf("%s", p); len = strlen(p); memset(d, 0, sizeof(d)); printf("%d\n", pi(0)); } return 0; } | cs |
>> isSame() 등의 함수에서 for 문의 조건식을 s+cnt-1 로 해야했는데, 계속 cnt-1 로 해서 시간을 많이 소비했다..ㅜ
'PS > 종만북' 카테고리의 다른 글
[TRIPATHCNT] 삼각형 위의 최대 경로 수 세기 (0) | 2018.04.15 |
---|---|
[TILING2] 타일링 (0) | 2018.04.15 |
[LIS] 최대 증가 부분 수열 (0) | 2018.04.13 |
[TRIANGLEPATH] 삼각형 위의 최대경로 (0) | 2018.04.10 |
[PICNIC] 소풍 (0) | 2018.04.09 |