Codeforces 1201E2. Knightmare (hard)

不羁岁月 提交于 2019-11-30 14:34:16

传送门

看到棋盘先黑白染色冷静一下

然后分析发现,如果初始时两只马在同色的格子,那么一定是后手吃先手

反之一定是先手吃后手

所以分类讨论一下,如果初始在同色的格子,并且后手到达终点的步数更少,那么后手一定赢

并且如果后手威胁到先手终点时的步数比先手到终点的步数少,那么后手下一步直接到先手终点,此时先手为了不被吃最多只能跳到离终点三步的位置(这个自己画一下图就很容易理解了),然后后手再花三步跳到自己终点即可,先手一定是赶不上的

否则,后手就没法阻止先手了

(先手总是有路可以用最短步数到达终点,后手如果可以把先手的最短路径都封锁那么此时后手到达自己终点的步数一定比较小)

总之,画图分类讨论一波

如果是不在同色格子就按先手能否赢讨论即可,都差不多,只是因为先手的原因,步数相等时先手比较快

具体实现看代码吧,代码参考:rui-de

$auto$ 大法好!(请使用 $C++14$ )

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int N=2007,xx[8]={1,2,2,1,-1,-2,-2,-1},yy[8]={2,1,-1,-2,-2,-1,1,2},INF=1e9;
int n,m,xa,ya,xb,yb;
int d1[N][N],d2[N][N];
struct poi {
    int x,y;
    poi (int _x=0,int _y=0) { x=_x,y=_y; }
};
queue <poi> Q;
void BFS(int sx,int sy,auto &mp)
{
    Q.push(poi(sx,sy)); mp[sx][sy]=0;
    while(!Q.empty())
    {
        poi u=Q.front(); Q.pop();
        for(int k=0;k<8;k++)
        {
            int tx=u.x+xx[k],ty=u.y+yy[k];
            if(tx<1||tx>n||ty<1||ty>m||mp[tx][ty]<INF) continue;
            mp[tx][ty]=mp[u.x][u.y]+1; Q.push(poi(tx,ty));
        }
    }
}
void dfs(int sx,int sy,auto &mp)
{
    for(int k=0;k<8;k++)
    {
        int tx=sx+xx[k],ty=sy+yy[k];
        if(tx<1||tx>n||ty<1||ty>m||mp[tx][ty]>=mp[sx][sy]) continue;
        cout<<tx<<" "<<ty<<endl; dfs(tx,ty,mp); break;
    }
}
int main()
{
    memset(d1,0x3f,sizeof(d1)); memset(d2,0x3f,sizeof(d2));
    cin>>n>>m; cin>>xa>>ya>>xb>>yb;
    BFS(n/2,m/2,d1); BFS(n/2+1,m/2,d2);
    int wht=d1[xa][ya],blk=d2[xb][yb];
    int w_b=d2[xa][ya],b_w=d1[xb][yb];
    if( ((xa+ya)&1) == ((xb+yb)&1) )
    {
        if(blk<wht) { printf("BLACK\n"); dfs(xb,yb,d2); return 0; }
        if( b_w-1<wht )
        {
            printf("BLACK\n");
            dfs(xb,yb,d1); dfs(n/2,m/2,d2);
            return 0;
        }
        printf("WHITE\n"); dfs(xa,ya,d1);
        return 0;
    }
    if(wht<=blk) { printf("WHITE\n"); dfs(xa,ya,d1); return 0; }
    if(w_b-1<=blk)
    {
        printf("WHITE\n");
        dfs(xa,ya,d2); dfs(n/2+1,m/2,d1);
        return 0;
    }
    printf("BLACK\n"); dfs(xb,yb,d2);
    return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!