您的位置:首页 > 大数据 > 人工智能

HDU 6139 Galaxy at War(2017 Multi-University Training Contest 8)

2017-08-18 15:22 666 查看
题目链接Galaxy at War

题意:在一个给定的n∗m的棋盘内的若干个位置(xi,yi)有wi个水晶,同时有t个冥想球和s个污染源,每一次可以选定一个位置(u,v),将t个水晶移动到(u+1,v)或者(u,v+1),如果这个位置有冥想球,那么可以在(u+1,v)和(u,v+1)处制造t个水晶。如果这个位置有污染源,那么只有⌊t2⌋个水晶能保存下来。(n,m)处有一个污染源,(n−1,m)处有一个冥想球。并且每一个冥想球和每一个污染源之间的距离是奇数。问维德和尤达大师轮流行动,不能行动的那一方输掉游戏,问维德是否能取得胜利。

题解:这个游戏是一个简单的阶梯博弈,因为在(n,m)处有污染源且所有冥想球与污染源的距离为奇数,那么我们只需要考虑与冥想球曼哈顿距离为偶数的的点即可。我们把这些点的水晶个数异或起来,如果是0,代表先手按照Nim博弈的取法取就行,因为后手不论怎么采取策略,先手一定有办法移动水晶使得局面必败(证明)。所以我们对于每一堆水晶,判断其是否和某一个它能够移动到的冥想球的曼哈顿距离为偶数,然后把这些堆的数目异或得到答案。由于从题意可以推出每一对冥想球之间的距离一定是偶数,所以我们直接判断是否和(n−1,m)处的冥想球距离为偶数即可,对于x=n的水晶记录x=n的冥想球y坐标最大值特判即可。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 500005;
pair<int,int> med
,pol
;
struct Ct{
int x,y,w;
Ct(){}
Ct(int x,int y,int w):x(x),y(y),w(w){}
};
vector<Ct>c;

int main(){
int T,n,m,k,x,y,w,t,s,mx;
scanf("%d",&T);
while(T--){
mx=0;
scanf("%d %d %d",&n,&m,&k);
c.clear();
for(int i=1;i<=k;i++){
scanf("%d %d %d",&x,&y,&w);
c.push_back(Ct(x,y,w));
}
scanf("%d",&t);
for(int i=1;i<=t;i++){
scanf("%d %d",&med[i].first,&med[i].second);
if(med[i].first==n)
mx=max(mx,med[i].second);
}
scanf("%d",&s);
for(int i=1;i<=s;i++)
scanf("%d %d",&pol[i].first,&pol[i].second);
int ans=0;
for(int i=0;i<k;i++){
if(c[i].x<n&&(abs(c[i].x-n+1)+abs(c[i].y-m))%2==0)
ans^=c[i].w;
else if(c[i].x==n&&c[i].y<=mx&&abs(c[i].y-mx)%2==0)
ans^=c[i].w;
}
puts(ans?"win":"lose");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐