hdu 1680 Cheesy Chess

hdu   1680   Cheesy Chess           题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1680

                            

题目大意:(好长的题啊……先赞一个!)二人对弈,白先黑后,棋盘固定8*8,白黑双方各执一子,白子曰白王(White King),黑子曰黑卒(Black Pawn)。棋盘上除了空格区域"."外还有两种区域,一种是D(Dangerous),另一种是F(Forbidden),规定F区两种棋都不能进入,D区只有白棋不能进入。再来说一下走法,白棋可以往邻接的8个方向走,而黑棋只能往正下方一个方向走。求哪一方赢并输出,所以要说一下胜利标准,白棋的目标是要抓到黑棋,如果白棋走到黑棋占据的格子里,白棋就赢了;任意一方如果走投无路了(轮到它走但它没法走了)另一方就赢了,如果黑棋已经走到最底层又轮到它走了,黑棋就赢了。还有一个比较有意思的point,黑棋的左下和右下两个格子总有两块D(卒前侍卫),它们是跟着黑棋走的。

题目分析:(在此提醒白先黑后,一步一步走)读懂题意其实就胜利了30%了,首先确定用BFS,然后分析一下胜利条件里的“走投无路”,只要白棋不是初始点周围围了8个不可走区域,它就不可能走投无路;黑棋的情况稍微复杂,如果黑棋的下方是F或白棋,黑棋就走投无路了。另外注意一下坑跌的输入,白棋和黑棋的位置输入之后要记得处理一下的。分析就到此为止了。

实现思路:说一下我是怎么实现的。以白棋为起点开始BFS,黑棋的当前位置x是黑棋的初始位置x+白棋的当前步数-1,y总是不变的,两个“卒前侍卫”的位置也容易推。剩下的都在代码里了。

code:

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
char map[10][10],vis[10][10][10];
int px,py,dir[8][2]= {1,0,-1,0,0,1,0,-1,1,1,1,-1,-1,1,-1,-1};
struct node
{
    int x,y,step;
}first,next;
bool judge(node a)
{
    if(a.x==px+a.step&&(a.y==py+1||a.y==py-1))return false;
    if(map[a.x][a.y]=='F'||map[a.x][a.y]=='D')return false;
    return a.x>=0&&a.y>=0&&a.x<8&&a.y<8&&!vis[a.x][a.y][a.step];
}
bool bfs(int kx,int ky)
{
    queue<node>q;
    vis[kx][ky][0]=true;
    first.x=kx,first.y=ky,first.step=0;
    q.push(first);
    while(!q.empty())
    {
        //printf("白在:%d,%d,step==%d\n",first.x,first.y,first.step);
        first=q.front();
        q.pop();
        if(map[px+first.step][py]=='F')
        {
            //printf("黑被挡住了\n");
            return true;
        }
        if(px+first.step>7)
        {
            //printf("黑到底了\n");
            return false;
        }
        for(int i=0; i<8; i++)
        {
            next.x=first.x+dir[i][0];
            next.y=first.y+dir[i][1];
            next.step=first.step+1;
            if(judge(next))
            {
                vis[next.x][next.y][next.step]=true;
                if(next.x==px+first.step&&next.y==py||next.x==px+next.step&&next.y==py)
                {//黑被抓住||黑被白堵死而走投无路
                    //printf("黑%d,%d被抓住了,%d,%d\n",px+first.step,py,first.x,first.y);
                    return true;
                }
                q.push(next);
            }
        }
    }
    //printf("over\n");
    return false;
}
int main()
{
    int i,kx,ky,t;
    //freopen("1.txt","r",stdin);
    scanf("%d",&t);
    while(t--)
    {
        memset(vis,false,sizeof(vis));
        for(i=0; i<8; i++)
        {
            scanf("%s",map[i]);
        }
        scanf("%d%d",&kx,&ky);
        scanf("%d%d",&px,&py);
        i=8-py;
        py=px-1;
        px=i;
        //printf("kx==%d,ky==%d,px==%d,py==%d\n",8-ky,kx-1,px,py);
        if(bfs(8-ky,kx-1))printf("White\n");
        else printf("Black\n");
    }
    return 0;
}
PS:好艰辛啊,被黑棋被白棋堵死这一种情况wrong了n+1次…… 抓狂





  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值