4053. 전국민 건강 프로젝트
시뮬레이션 문제 같은데 푸는데 꽤나 시간이 걸렸다..
문제의 조건을 보니 시간초과를 해결하는게 가장 중요해 보였다.
맨 처음에는 -> <- 이렇게 만나는 지점을 구하고, 그걸 찾아가면서 문제를 풀었더니 시간초과가 발생했다.
-><- 이 부분을 미리 알고 체크하고, 그걸 이용해서 문제를 풀어야 할 것 같았는데 방법이 잘 생각이 안났다.
수의 범위가 너무나 커서 배열로 하기도 그렇고.. 그래서 생각하던 중에 만들면서 큐에 집어넣는 방식으로 문제를 풀었다.
그리고 처음에 -><- 한번만 구했었는데, 생각해보니 0 인 부분( 사람이 만나는 부분)은 사실 -> 와 <- 역할을 할 수 있다.
따라서 그 부분만을 계속 적으로 0으로 만들면서, 그니까 사람이 만나는 부분을 계속 만들고
마지막에 for문 한번으로 사람이 안만나는 것들을 정리해주면 된다.
<정답 코드>
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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #include<iostream> #include<vector> #include<string.h> #include<queue> using namespace std; int N, Q; long long T; typedef struct { long long p; long long d; }person; person per[100001]; int main() { ios::sync_with_stdio(false); cin.tie(NULL); //freopen("input.txt", "r", stdin); int tc; cin >> tc; for (int t = 1; t <= tc; t++) { memset(per, 0, sizeof(per)); queue<int> q; cin >> N >> T >> Q; for (int i = 0; i < N; i++) { cin >> per[i].p >> per[i].d; if (per[i].d == 2) { per[i].d = -1; } } // -> <- 사람이 만나는 부분 큐에 넣기 for (int i = 0; i < N - 1; i++) { if (per[i].d == 1 && per[i+1].d == -1) { q.push(i); i++; } } // 사람이 만나는 부분 계속 업데이트 while (!q.empty()) { int i = q.front(); q.pop(); if (per[i].d == 0 && per[i + 1].d == 0) { continue; } if (i + 1 < N) { long long p1 = per[i].p + per[i].d*T; long long p2 = per[i + 1].p + per[i + 1].d*T; //-> <- 부분 체크 if (per[i].d == 1 && per[i + 1].d == -1 && p1 >= p2) { if (i + 1 < N) { q.push(i + 1); } if (i - 1 >= 0) { q.push(i - 1); } per[i].d = 0; per[i + 1].d = 0; per[i].p = per[i + 1].p = (per[i].p + per[i + 1].p) / 2; } // -> 0 이 부분 체크 else if (per[i].d == 1 && per[i + 1].d == 0 && p1 >= p2) { if (i - 1 >= 0) { q.push(i - 1); } if (i + 1 < N) { q.push(i + 1); } per[i].d = 0; per[i].p = per[i + 1].p; } // 0 <- 이부분 체크 else if (per[i].d == 0 && per[i + 1].d == -1 && p1 >= p2) { if (i - 1 >= 0) { q.push(i - 1); } if (i + 1 < N) { q.push(i + 1); } per[i + 1].d = 0; per[i + 1].p = per[i].p; } } } //나머지 사람이 만나지 않는 부분 정리 for (int i = 0; i < N; i++) { if (per[i].d != 0) { per[i].p += per[i].d*T; } } vector<long long> x; for (int i = 0; i < Q; i++) { int tmp; cin >> tmp; x.push_back(per[tmp-1].p); } cout << "#" << t << " "; for (int i = 0; i < x.size(); i++) { cout << x[i] << " "; } cout << "\n"; } return 0; } | cs |
반응형
'알고리즘 > SW EXPERT' 카테고리의 다른 글
3124. 최소 스패닝 트리 (0) | 2018.03.23 |
---|---|
4050. 재관이의 대량 할인 (0) | 2018.03.21 |
3809. 화섭이의 정수 나열 (0) | 2018.03.10 |
3503. 초보자를 위한 점프대 배치하기 (0) | 2018.03.05 |
3289. 서로소 집합 (0) | 2018.03.04 |