10Catch him

简单题意

输入给出准备擒杀四分卫的防守球员的位置、对方每个进攻锋线球员的位置以及对方四分卫的位置,你的任务是求出这名准备擒杀的防守球员至少要移动多少步,才能够擒杀对方四分卫。假设对方进攻锋线和四分卫在这个过程中都不会移动。只有1名防守球员,防守球员只要碰到对方四分卫就算擒杀。所有的球员都是一块连续的、不中空的2维区域。防守球员不可以从进攻锋线的身体上穿过,也不可以从界外穿过(只能走空地)。防守队员不可以转动身体,只能平移。防守队员的身体所有部分向同一个方向(上、下、左、右)移动1格的过程叫做1步。

解题思路形成过程

讲真看题都没看懂,不是很懂足球,去看看大神怎么说(服了这个题抓狂):将整体用 一个点x,y加上其他点的相对位移来表示,身体的每一个部分用一个数字来标记依次标为:1,2,3,4,5...  移动过程中,相同的标记点不能重复走过,也就是说,身体的某个部分走过的点,不能再走第二遍,而其他点可以,例如,第一个节点标记为1,它不能再走标记为1的点。好像就是广搜。

感想

读懂题好难,做为一个ACMer真的需要啥都知道

AC代码

#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
char cmap[110][110];  //定义map
int mark[110][110];        //定义标记
struct Node
{
    int x,y,step;
}d,p;      //节点,注意节点只 存其中一个点即可
int bx[30],by[30];     //存有相对位置的数组
int cx[]={1,-1,0,0};
int cy[]={0,0,-1,1};
int bfs(int len,int m,int n,int x,int y)
{
    int i,j;
    queue<Node> q;
    memset(mark,0,sizeof(mark));
    d.x=x;
    d.y=y;
    d.step=0;
    q.push(d);
    for(i=0;i<len;i++)
        mark[bx[i]][by[i]]=i+1;   //用位置标记
    while(!q.empty())
    {
        d=q.front();
        q.pop();
        for(i=0;i<len;i++)
            if(cmap[d.x+bx[i]][d.y+by[i]]=='Q')
                return d.step;
        for(i=0;i<4;i++)
        {
            p.x=d.x+cx[i];
            p.y=d.y+cy[i];
            p.step=d.step+1;

            //进行条件判断
            for(j=0;j<len;j++)
            {
                int tx,ty;
                tx=p.x+bx[j];
                ty=p.y+by[j];
                if(cmap[tx][ty]=='O'||tx<0||tx>=m||ty<0||ty>=n||mark[tx][ty]==j+1)
                    break;
            }
            if(j<len)
                continue;   //若是break出来的就不进入push和标记
            q.push(p);

            //标记
            for(j=0;j<len;j++)
            {    
                int tx,ty;
                tx=p.x+bx[j];
                ty=p.y+by[j];
                mark[tx][ty]=j+1;
            }
        }
    }
    return 0;
}
int main()
{
    int m,n;
    while(~scanf("%d%d",&m,&n))
    {
        if(!m&&!n)
            break;
        int i,j,k;
        for(i=0;i<m;i++)
            scanf("%s",cmap[i]);
        for(k=i=0;i<m;i++)
            for(j=0;j<n;j++)
            {
                if(cmap[i][j]=='D')
                {
                    bx[k]=i;
                    by[k]=j;
                    k++;
                }
            }
        int sx=bx[0],sy=by[0];
        for(i=0;i<k;i++)    //生成相对位置数组
        {
            bx[i]-=sx;
            by[i]-=sy;
        }
        int ans=bfs(k,m,n,sx,sy);
        if(ans)
            printf("%d\n",ans);
        else
            puts("Impossible");
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值