※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 4324번 문제인 XYZZY이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/4324
4324번: XYZZY
The input consists of several test cases. Each test case begins with n, the number of rooms. The rooms are numbered from 1 (the start room) to n (the finish room). Input for the n rooms follows. The input for each room consists of one or more lines contain
www.acmicpc.net
먼저 1번 방에서
위의 풀이가 비효율적인 이유는 위와 같이 사이클을 여러 번 돌아
그렇지 않다. 이 문제에서는
사이클을 돌아야 하는 경우와 그럴 필요가 없는 두 경우 모두에 신경써 문제를 해결하자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <cstring>
#include <utility>
using namespace std;
int N, K;
int E[101];
vector<int> G[101], invG[101];
int HP[101], tmp[101], mxHP[101], oldmxHP[101];
int chk[101], visited[101], ans;
void dfs(int cur) {
visited[cur] = 1;
if (chk[cur]) ans = 1;
for (auto &nxt:invG[cur]) {
if (visited[nxt]) continue;
dfs(nxt);
}
}
void solve() {
for (int i = 1; i <= N; i++) G[i].clear(), invG[i].clear();
for (int i = 1; i <= N; i++) {
cin >> E[i] >> K;
G[i].clear();
while (K--) {
int x; cin >> x;
G[i].emplace_back(x);
invG[x].emplace_back(i);
}
}
if (N == 1) {
cout << "winnable\n";
return;
}
memset(HP, 0xff, sizeof(HP));
memset(mxHP, 0xff, sizeof(mxHP));
HP[1] = mxHP[1] = 100;
for (int k = 0; k < N; k++) {
memset(tmp, 0xff, sizeof(tmp));
for (int cur = 1; cur <= N; cur++) {
if (HP[cur] < 0) continue;
for (auto &nxt:G[cur]) {
if (HP[cur] + E[nxt] < 1) continue;
tmp[nxt] = max(tmp[nxt], HP[cur] + E[nxt]);
}
}
swap(HP, tmp);
if (HP[N] > 0) {
cout << "winnable\n";
return;
}
for (int i = 1; i <= N; i++) mxHP[i] = max(mxHP[i], HP[i]);
}
for (int i = 1; i <= N; i++) oldmxHP[i] = mxHP[i];
for (int k = 0; k < N; k++) {
memset(tmp, 0xff, sizeof(tmp));
for (int cur = 1; cur <= N; cur++) {
if (HP[cur] < 0) continue;
for (auto &nxt:G[cur]) {
if (HP[cur] + E[nxt] < 1) continue;
tmp[nxt] = max(tmp[nxt], HP[cur] + E[nxt]);
}
}
swap(HP, tmp);
if (HP[N] > 0) {
cout << "winnable\n";
return;
}
for (int i = 1; i <= N; i++) mxHP[i] = max(mxHP[i], HP[i]);
}
memset(chk, 0, sizeof(chk));
for (int i = 1; i <= N; i++) {
if (mxHP[i] > oldmxHP[i]) chk[i] = 1;
}
memset(visited, 0, sizeof(visited)), ans = 0;
dfs(N);
if (ans) cout << "winnable\n";
else cout << "hopeless\n";
}
int T;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N;
while (N > 0) {
solve();
cin >> N;
}
}
'BOJ' 카테고리의 다른 글
[BOJ 4626 // C++] 가글 (0) | 2024.04.25 |
---|---|
[BOJ 14515 // C++] Yin and Yang Stones (0) | 2024.04.24 |
[BOJ 23604 // C++] Chinese Remainder Theorem (0) | 2024.04.22 |
[BOJ 16481 // C++] 원 전문가 진우 (0) | 2024.04.21 |
[BOJ 16509 // C++] 장군 (1) | 2024.04.20 |