//思路很简单:通过广搜记录国王到达某个点的最短时间,通过双for循环记录勇士到达某个点的最短时间;然后找其
中较大的那个(不过如果
国王先到达的时候需要考虑特殊情况),此题情况要考虑周全。
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int n,m,k;
int xk,yk,xt,yt;
int ans;
bool f[1010][1010];///数组大小分配问题,我也是脑残了
const int ary[8][2]= {{-1,-2},{-2,-1},{-2,1},{-1,2},{1,-2},{2,-1},{2,1},{1,2}};
int tans[1010][1010];///其实这个可以不需要,在广搜的时候可以直接判断
int kans[1010][1010];
typedef struct node
{
int x,y;
int step;
} Node;
queue<Node> q;
void init_tans(int x,int y)
{
while(!q.empty())
q.pop();
Node tmp;
tmp.x=x;
tmp.y=y;
tmp.step=0;
q.push(tmp);
f[tmp.x][tmp.y]=true;///对国王初始点进行标记,已经访问过
while(!q.empty())
{
Node* cnode=&q.front();
q.pop();
for(int i=0; i<8; i++)
{
Node tmp;
tmp.x=cnode->x+ary[i][0];
tmp.y=cnode->y+ary[i][1];
tmp.step=cnode->step+1;
if(tmp.x>=1&&tmp.x<=n&&tmp.y>=1&&tmp.y<=m&&!f[tmp.x][tmp.y])
{
f[tmp.x][tmp.y]=true;
tans[tmp.x][tmp.y]=tmp.step;
q.push(tmp);///竟然忘记入队列了
}
}
}
}
void init_kans()
{
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
int tm;
if(i<xk)
tm=xk-i;
else
tm=i-xk;
if(j<yk)
{
if(tm<yk-j)
tm=yk-j;
}
else
{
if(tm<j-yk)
tm=j-yk;
}
kans[i][j]=tm;
}
}
int main()
{
int T;
scanf("%d",&T);
for(int t=1; t<=T; t++)
{
scanf("%d%d%d",&n,&m,&k);
scanf("%d%d",&xk,&yk);
scanf("%d%d",&xt,&yt);
memset(f,0,sizeof(f));
memset(tans,0,sizeof(tans));
memset(kans,0,sizeof(kans));
init_tans(xt,yt);
init_kans();
tans[xt][yt]=2;
kans[xk][yk]=2;
int ans=201;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
if(kans[i][j]!=0&&tans[i][j]!=0)
{
/// int tmp=max(kans[i][j],tans[i][j]);此处出现问题
int tmp;//勇士到达某一点的时间可以是>=最短时间的任何值
if(kans[i][j]>tans[i][j])
tmp=kans[i][j];
else{
//对国王应进行特殊处理,国王到达某一个点的时间是最短时间+2的倍数(特殊情况,如果国王提前到达)
if((tans[i][j]-kans[i][j])%2==0)
tmp=tans[i][j];
else
tmp=tans[i][j]+1;
}
if(ans>tmp)
ans=tmp;
}
}
printf("Case #%d:\n",t);
if(ans<=k)
printf("%d\n",ans);
else
printf("OH,NO!\n");
}
return 0;
}