首页 > 其他 > 详细

bzoj:1457: 棋盘游戏

时间:2017-04-05 21:29:07      阅读:213      评论:0      收藏:0      [点我收藏+]

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1457

看了网上dalao的题解,好像解释得并不是很清楚,就按照那种思路,自己YY了一个想法,写出来居然跟std是一样的。

首先如果刚开始棋盘上有X=0或Y=0或X==Y先特判掉。

如果我们把走到(0,0)对应于将一堆石子取空,那么剩下的难点在于一般的Nim游戏是所有石子堆均被取空则游戏结束,而这里只要一堆空就结束了,这很气……

那么我们需要考虑转换一下一堆石子被取空时对应的情景。

如果有人走到X=0或Y=0或X==Y,对手即刻就胜利了,最优策略里谁都不会这么走,也就是说,走到X=0或Y=0或X==Y这种情况是不被允许的。要是有人实在没办法走别的地方,必须走这里,他就输了。这里就转化为不允许走到X=0或Y=0或X==Y,谁无法在这一限制内继续行动,就是失败者。

这样一来就是正常的Nim题了。

技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MN 1000
using namespace std;

int read_p,read_ca;
inline int read(){
    read_p=0;read_ca=getchar();
    while(read_ca<0||read_ca>9) read_ca=getchar();
    while(read_ca>=0&&read_ca<=9) read_p=read_p*10+read_ca-48,read_ca=getchar();
    return read_p;
}
int T,n,m,a,b,mmh,MMH,sg[100][100];
bool bo[1001];
int main(){
    register int i,j;
    for (i=1;i<100;i++)
    for (j=1;j<100;j++)
    if (i!=j){
        memset(bo,0,sizeof(bo));
        for (int k=1;k<i&&k<j;k++) bo[sg[i-k][j-k]]=1;
        for (int k=1;k<i;k++) if (i-k!=j) bo[sg[i-k][j]]=1;
        for (int k=1;k<j;k++) if (i!=j-k) bo[sg[i][j-k]]=1;
        for (int k=0;;k++) if (!bo[k]){sg[i][j]=k;break;}
    }
    T=read();
    while (T--){
        n=read();mmh=MMH=0;
        while (n--){
            a=read();b=read();
            if (a==0&&b==0) MMH|=2;
            if (a==0||b==0||a==b) MMH|=1;else mmh^=sg[a][b];
        }
        if (MMH) puts(MMH==1?"^o^":"T_T");else puts(mmh?"^o^":"T_T");
    }
}
View Code

YY成功真开心。

bzoj:1457: 棋盘游戏

原文:http://www.cnblogs.com/Enceladus/p/6670606.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!