下棋
Time Limit: 6000/3000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
这个题感觉还是很有意思的。
注意到马跳到一个位置所需步数的奇偶性是不能发生改变的,因为其每跳一步x+y的奇偶性是一定会发生改变的。而对于国王来说,如果国王走k步能到一个位置,那么国王走>=k步一定能到这个位置。所以我们可以首先BFS出王和马到一个位置的最短步数,然后枚举每一个位置。判断一下,如果是王先到这里,那么马到这里的步数就是它们在这里相遇的最短步数;如果是马先到这里,那么最小的大于等于王的步数且与马的最短步数奇偶性相同的数就是王和马在这里相遇的最短时间。
#include<cstdio>
#include<iostream>
using namespace std;
#include<cstring>
int d[2][1005][1005];
int qx[1000005],qy[1000005];
int dx[2][10]={{1,2,1,2,-1,-2,-1,-2},{1,1,1,0,0,-1,-1,-1}},dy[2][10]={{2,1,-2,-1,2,1,-2,-1},{1,0,-1,1,-1,1,0,-1}};
int N,M;
bool check(int x,int y){
return x>0&&x<=N&&y>0&&y<=M;
}
int main(){
int T,K;
scanf("%d",&T);
int x[5],y[5],h,t,i,j,D,ans,tmp;
for(int Case=1;Case<=T;++Case){
scanf("%d%d%d%d%d%d%d",&N,&M,&K,x+1,y+1,x,y);
memset(d,127,sizeof(d));
for(D=0;D<2;++D){
qx[0]=x[D],qy[0]=y[D],d[D][x[D]][y[D]]=0;
for(h=0,t=1;h!=t&&d[D][qx[h]][qy[h]]<K;++h)
for(i=0;i<8;++i)
if(check(qx[t]=qx[h]+dx[D][i],qy[t]=qy[h]+dy[D][i])&&d[D][qx[t]][qy[t]]>1E5){
d[D][qx[t]][qy[t]]=d[D][qx[h]][qy[h]]+1;
++t;
}
}
ans=0x7fffffff;
for(i=N;i;--i)
for(j=M;j;--j){
if(d[0][i][j]<=d[1][i][j])ans=min(ans,d[1][i][j]+(d[0][i][j]&1^d[1][i][j]&1));
else if(d[0][i][j]>1)ans=min(ans,d[0][i][j]);
}
printf("Case #%d:\n",Case);
if(ans<=K)printf("%d\n",ans);
else puts("OH,NO!");
}
}