ABC 209 E - Shiritori
作者:互联网
E - Shiritori
对抗博弈,BFS,哈希
-
对于每个字符串,设前三位哈希值为 a,后三位哈希值为 b,则可用 b 来代表该字符串,连一条 a -> b 表示若当前是 a 字符串,可以变成 b
-
反向建图,连 b -> a 的边,则入度为 0 的边就是原图的终点,是必败态,赋 0,并将其放入队列
-
bfs 过程中,有如下性质
- 必败态 b 的下一个点 a 是必胜态(若当前在 a 点,可选择走到 b 点,对手必败)
- 必胜态 b 的下一个点 a,若 a 的入度为 0,则 a 是必败态(若当前在 a 点,入度为 0 说明 a 只能往 b 走,所以对手必胜); 若 a 的入度不为 0,则 a 并不能确定状态(当前在 a 的这个人肯定不愿走到 b 让对手必胜,所以要等别的选择)
- 已经放入队列的点表示这个点的状态已经确定了
-
类似拓扑排序,每次搜到一个点要将它的入度减 1
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
using namespace std;
#define endl "\n"
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
int din[N], id[N], ans[N];
int n;
int f(char x)
{
if (x >= 'a' && x <= 'z')
return x - 'a';
return x - 'A' + 26;
}
int hs(string s)
{
return f(s[0]) * 52 * 52 + f(s[1]) * 52 + f(s[2]);
}
vector<vector<int> > G(N);
void add(int u, int v)
{
G[u].push_back(v);
din[v]++;
}
void bfs()
{
queue<int> q;
for (int i = 0; i < N; i++)
{
if (!din[i])
{
ans[i] = 0;
q.push(i);
}
}
while(!q.empty())
{
int u = q.front();
q.pop();
for (auto v : G[u])
{
if (ans[v] == -1)
{
din[v]--;
if (ans[u] == 0)
{
ans[v] = 1;
q.push(v);
}
else if (din[v] == 0)
{
ans[v] = 0;
q.push(v);
}
}
}
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
{
string s;
cin >> s;
int u = hs(s.substr(0, 3)), v = hs(s.substr(s.size() - 3));
add(v, u);
id[i] = v;
}
memset(ans, -1, sizeof ans);
bfs();
for (int i = 1; i <= n; i++)
{
int u = id[i];
if (ans[u] == 1)
cout << "Aoki" << endl;
else if (ans[u] == 0)
cout << "Takahashi" << endl;
else
cout << "Draw" << endl;
}
return 0;
}
标签:Shiritori,din,ABC,209,入度,int,ans,push,include 来源: https://www.cnblogs.com/hzy717zsy/p/16356747.html