일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Cycle detecting
- dynamic programming
- BOJ
- Sieve_of_Eratosthenes
- DynamicProgramming
- Algospot
- Dag
- graph modeling
- disjoint-set
- hashing
- Euler circuit
- flows
- 백준
- BST
- BFSDFS
- mathematics
- graph
- Eulerian path
- implementation
- bitmask
- GCD
- Greedy
- Eulerian circuit
- backtracking
- CS Academy
- POJ
- Segment Tree
- scc
- Shortest path
- Euler path
- Today
- Total
그냥 하는 노트와 메모장
BOJ 2593 - 엘리베이터 본문
i번째 엘리베이터를 수식으로 나타낸다면 첫 위치를 그리고 몇칸씩 이동할 수 있는지를 로 표현한다면 i번째 엘리베이터가 갈 수 있는 곳은 아래를 만족하는 모든 층에 갈 수 있다.
하지만 최고층이 N이기 때문에 y는 최대 N까지 밖에 갈 수 없다. 따라서 엘리베이터에 따라 k의 최대값이 달라진다.
모든 엘리베이터를 수식으로 두고, 서로 다른 두 엘리베이터에 대해 i에서 j로 갈 수 있는지를 판단한다. 만약 i 엘베에서 j 엘베로 갈 수 있다면 간선을 연결해준다.
이 때 간선을 연결해줄 알고리즘이 매우 까다롭다. 두 수식에 대해서 만족하는 해와 최대층 N에 대해서 처리를 해줘야하기 때문이다.
우선 두 수식을 아래처럼 나타낸다.
이제 꼴로 나타냈으니 수식의 해가 정수해이기 위해선(정수해인 이유는 엘베에 대해 한층 올라가는 것은 실수가 아니라 정수이기 때문) 가 일단 에 대해 나눠떨어져야 확장 유클리드를 사용할 수 있다. 나눠떨어지지 않는다면 정수해가 존재하지 않기 때문에 바로 종료, i와 j 간의 간선을 생성해주지 않는다.
만약 나눠떨어졌다면, 를 로 두고, 마지막인 x를 빼버렸다고 생각하고 확장 유클리드를 구한다. 나중에 확장 유클리드를 구한 해가 (x1, y1)이였다면 우리가 실재로 구해야하는 해는 (x1*x, y1*x)가 된다.
확장 유클리드를 이용하여 두 해에 대해 가장 작은 음이 아닌 정수의 짝을 찾고, 두 수식에 대입하여 N층을 넘어가는지 판단한다. 이는 곧 두 엘베가 같은 층에 멈출 수 있는 곳을 찾는 것이고 최대층이 N이므로 같은 층에 멈추는 가장 낮은 층이 N을 넘어가면 간선을 이어주지 못하는 것이다.
만약 이 값도 N보다 작다면 i번째 엘베에서 j번째 엘베로 이동이 가능하단 소리다.
다음으로 A와 B에 대해서 이용할 수 있는 모든 엘리베이터를 조사한다. 이는 단순 나머지 연산과 시작점을 이용하여 구할 수 있다.
#include <cstdio> #include <queue> #include <vector> #include <cstring> #include <stack> using namespace std; int abs_v(int a) { return a < 0 ? -a : a; } int N; int gcd(int a, int b) { int t; while (b) { t = a%b; a = b; b = t; } return a; } bool ex_euclid(int a, int b,int sbsa, int sb, int sa) { int r0 = a, r1 = b, s0 = 1, s1 = 0, t0 = 0, t1 = 1,q,r,s,t; while (r1) { q = r0 / r1; r = r0 - q*r1; if (r < 0) { r0 -= r1; q = r0 / r1; r += r1; } r0 = r1; r1 = r; s = s0 - q * s1; s0 = s1; s1 = s; t = t0 - q * t1; t0 = t1; t1 = t; } s0 *= sbsa / r0; t0 *= sbsa / r0; int lcm = (-a)*b / r0,aa = lcm/(-a),bb = lcm/b; while (s0 < 0 || t0 < 0) s0 += aa, t0 += bb; while (s0 - aa >= 0 && t0 - bb >= 0) s0 -= aa, t0 -= bb; s0 %= b, t0 %= (-a); int ea = b*t0 + sb, eb = (-a)*s0+sa; return ea <= N && eb <= N; } int main1() { N = 20; int a, b, s1, s2,g; a = 3, b = 8; s1 = 1, s2 = 12; g = gcd(a, b); if ((s2 - s1) % g == 0) { if (s2 > s1) ex_euclid(-b, a,s2-s1, s1,s2); else ex_euclid(-a , b ,s1-s2, s2,s1); } return 0; } int main() { int M, A, B, ev[100][2], i, j, a, b, c, vi[100], u, f = 1,mini=1e9,sa,sb,g,uv; scanf("%d%d", &N, &M); vector<vector<int>> adj(M); vector<int> src, sink; stack<int> ans; for (i = 0; i < M; i++) { scanf("%d%d", &ev[i][0], &ev[i][1]); for (j = 0; j < i; j++) { a = ev[j][1], b = ev[i][1]; sa = ev[j][0], sb = ev[i][0]; c = sb-sa; g = gcd(a, b); uv = 0; if ((sb - sa) % g == 0) { if (sb > sa) uv = ex_euclid(-b, a, sb - sa, sa,sb); else uv = ex_euclid(-a, b, sa - sb, sb,sa); } if (uv) { adj[i].push_back(j); adj[j].push_back(i); } } } scanf("%d%d", &A, &B); for (i = 0; i < M; i++) { if (A - ev[i][0] >= 0 && (A - ev[i][0]) % ev[i][1] == 0) src.push_back(i); if (B - ev[i][0] >= 0 && (B - ev[i][0]) % ev[i][1] == 0) sink.push_back(i); } if (A == B) mini = 0; queue<int> q; for (int s : src) { memset(vi, -1, sizeof(vi)); q.push(s); while (!q.empty()) { u = q.front(), q.pop(); for (int v : adj[u]) if (vi[v] == -1) { vi[v] = u; q.push(v); } } for (int t : sink) { if (vi[t] == -1) continue; stack<int> trace; for (i = t; i != s; i = vi[i]) trace.push(i); trace.push(s); if (trace.size() < mini) { mini = trace.size(); ans = trace; } f = 0; } } if (f) printf("-1"); else { printf("%d\n", ans.size()); while (!ans.empty()) { printf("%d\n", ans.top()+1); ans.pop(); } } return 0; }
'Solved problems' 카테고리의 다른 글
BOJ 1111 - IQ Test (0) | 2018.01.16 |
---|---|
BOJ 1415 - 사탕 (0) | 2018.01.16 |
BOJ 2679 - Route Redundancy(맨체스터의 도로) (0) | 2018.01.09 |
BOJ 2026 - 소풍 (0) | 2018.01.09 |
BOJ 3409 - Word equations(문자 방정식) (1) | 2018.01.07 |