0
点赞
收藏
分享

微信扫一扫

2018 China Collegiate Programming Contest J. Stone Game(博弈,拓扑图)

small_Sun 2022-02-08 阅读 36
i++iosc++


​​传送门​​

简单模拟过后,我们发现如果一个数比两边都小的话

这个数最后一定会变成零

比如1 2 3 2 5 1 6 7

首先可以确定1 2 1会变成零,也就是

0 2 3 0 5 0 6 7

那么可以发现和 0 0 0相邻的可以变成 1 1 1…

但是其中 3 3 3也和 0 0 0相邻,但是因为左边的 2 2 2比自己小,所以不能小于左边的数

左边的 2 2 2可以变成 1 1 1,那么自己只能变成 2 2 2

我们发现,在相邻的数字=中,大的数依赖于小的数

这其实就是一张有向无环图,由小的数字像相邻大的数字连边去拓扑排序

不断松弛即可

拓扑代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e6+10;
int in[maxn],t,n,a[maxn],f[maxn],casenum;
vector<int>vec[maxn];
void add(int u,int v){ vec[u].push_back( v ); in[v]++; }
void tuopu()
{
queue<int>q;
for(int i=1;i<=n;i++)
if( a[i]<a[i-1]&&a[i]<a[i+1] ) { f[i]=0; q.push( i ); }
while( !q.empty() )
{
int u = q.front(); q.pop();
for(int i=0;i<vec[u].size();i++)
{
int v = vec[u][i];
f[v] = max( f[v],f[u]+1 );
if( --in[v]==0 ) q.push( v );
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> t;
while( t-- )
{
int sum = 0;
cin >> n;
for(int i=1;i<=n;i++){ cin >> a[i]; sum += a[i]; }
a[0] = a[n+1] = 1e9+1;
for(int i=1;i<=n;i++)
{
if( a[i]<a[i-1]&&i-1>=1 ) add(i,i-1);
if( a[i]<a[i+1]&&i+1<=n ) add(i,i+1);
}
tuopu();
for(int i=1;i<=n;i++)
{
sum-=f[i],f[i]=0;
vec[i].clear();
}
cout << "Case " << ++casenum << ": ";
if( sum%2==1 ) cout << "Alice\n";
else cout << "Bob\n";
}
}

b f s bfs bfs代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e6+10;
int in[maxn],t,n,a[maxn],f[maxn],casenum;
void bfs()
{
queue<int>q;
for(int i=1;i<=n;i++)
if( a[i]<a[i-1]&&a[i]<a[i+1] ) { f[i]=0; q.push( i ); }
while( !q.empty() )
{
int u = q.front(); q.pop();
if( u-1>=1&&a[u-1]>a[u] )
{
f[u-1] = max( f[u-1],f[u]+1 );
q.push( u-1 );
}
if( u+1<=n&&a[u+1]>a[u] )
{
f[u+1] = max( f[u+1],f[u]+1 );
q.push( u+1 );
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> t;
while( t-- )
{
int sum = 0;
cin >> n;
for(int i=1;i<=n;i++){ cin >> a[i]; sum += a[i]; }
a[0] = a[n+1] = 1e9+1;
bfs();
for(int i=1;i<=n;i++)
sum-=f[i],f[i]=0;
cout << "Case " << ++casenum << ": ";
if( sum%2==1 ) cout << "Alice\n";
else cout << "Bob\n";
}
}



举报

相关推荐

0 条评论