题面翻译
本题是一道交互题。
本题需要你编写一个国际象棋中单后杀王的程序,和交互库对弈。 本题的规则和一般国际象棋中的规则有所不同,请认真阅读。
国际象棋棋盘是 \(8\times 8\) 的正方形网格。本题中,所有行从上到下分别编为 \(1\sim 8\) 行,所有列从左到右分别编为 \(1\sim 8\) 列;记同时处在第 \(r\) 行、第 \(c\) 列的格子为格子 \((r,c)\)。
在游戏的开始,你需要确定并告知交互库皇后的初始坐标。接着,交互库会秘密地把国王放至棋盘上任何一个格子。然后,游戏开始,双方轮流走棋,由交互库先行。
皇后的 行走范围 为所有和皇后同行、同列或者同在一条 \(45^\circ\) 斜线上的格子。也就是说,设皇后当前在格子 \((r,c)\),则皇后下一步能走到格子 \((x,y)\),当且仅当 \((r,c)\neq (x,y)\),且 \(r=x\) 或 \(c=y\) 或 \(|r-x|=|c-y|\)。注意:在一步棋中,不允许将皇后停在原地不动。
国王的 行走范围 为其紧邻的 \(8\) 个格子。也就是说,也就是说,设国王当前在格子 \((r,c)\),则国王下一步能走到格子 \((x,y)\),当且仅当 \((r,c)\neq (x,y)\),且 \(\max \{|r-x|,|c-y|\}=1\)。国王不能停在原地不动,不能走入皇后所在的格子,也不能走入皇后的行走范围中。 如果国王无法移动,那么游戏结束,你获得胜利。特别地,如果游戏开始时国王和皇后处于同一位置,那么你直接获胜。
游戏开始后,你和交互库将通过输入输出交流各自走棋的位置(具体格式见下文)。你需要在 \(130\) 步内获得胜利,如果你在行走 \(130\) 步后国王仍有合法移动,那么视作你失败。你需要写一个程序,在规定的步数内获得胜利。
交互细节
本题一个测试点含多组测试数据。你需要首先从标准输入中读入一个正整数 \(t(1\leq t\leq 60)\),表示测试数据组数。你们接下来将进行 \(t\) 次游戏。
每次游戏开始时,你需要先输出两个正整数 \(x\ y\),表示你选择的皇后坐标。接着交互库会选择国王的坐标(但不会告诉你)。接着从交互库开始,双方轮流行动。
当交互库行动时,你需要读入一个字符串 \(S\)。\(S\) 的取值可能有如下几种:
Done
:表示交互库无法找到合适的着法,你获胜。如果是最后一组数据则请退出程序;否则请准备下一组数据。Right
,Left
,Up
,Down
,Down-Right
,Down-Left
,Up-Right
,Up-Left
:分别表示国王向右、左、上、下、右下、左下、右上、左上走了一步。
当你行动时,你需要输出两个整数 \(x\ y\) 表示你移动到的坐标。你需要保证坐标合法。
题解
考虑初始将后放置在\((1,1)\)。
我们需要时刻保证王在后下方,显然完成放置后之后的 \(1\) 个时刻是满足的。
之后如何保证?
首先王不可能跟后处在同一行。
若王在后下方 \(2\) 行及以上,后可以向下一行。
若王向下一行,则后也可以向下一行。
若王在后下方 \(1\) 行,后不能向下,因为王有可能可以向上 \(1\) 行,这样后就在王下方了。
怎么办?
设当前后处在第 \(x\) 行,王处在第 \(x+1\) 行 \((1<=x<=7)\)。只需将后移动至 \((x,1)\),然后后每次向右一格,在移动至 \((x,8)\) 之前,无视王左右移动,总有一个时刻王会向下,那么后也向下即可。
王向上怎么办?若王处在后下方 \(2\) 行以上,向上是无影响的,若王恰好处在后下方 \(2\) 行,向上后就到了后下方 \(1\) 行。
注意到王至多向上七次,因此每次王向上之后将后移至后所在当前行的最左侧,然后每次向右一格直至王向下即可。
所以整个流程就是初始将后放置在 \((1,1)\),对于每一行,后都从 \((x,1)\) 移到 \((x,8)\),若王向下,后也向下,然后移至最左侧即可,若王向上,后移至最左侧即可。
总的步数不超过 \(8*8+7*8=120\),可以通过本题,实际上这很松,因为后不可能每次都需要从最左侧移至最右侧,即使王走到最右侧,后在第 \(7\) 列时王也得向下走了。
如果后位于 \((x,1)\) 时就需要向下,可以直接走到 \((x+1,2)\) ,能省点步数,不过没什么关系。
代码
#include<bits/stdc++.h>
#define For(i,l,r) for(int i=(l);i<=(r);++i)
#define FF fflush(stdout)
using namespace std;
int now_x,now_y;
string query()
{
printf("%d %d\n",now_x,now_y);
FF;
string opt;
cin>>opt;
return opt;
}
void solve()
{
now_x=1,now_y=1;
bool flag=false;
string opt=query();
if(opt=="Done")
return;
while(opt!="Done")
{
if((opt=="Up") || (opt=="Up-Left") || (opt=="Up-Right") || (flag==true))
{
if(now_y==1)
now_y=2;
else
now_y=1;
flag=false;
opt=query();
}
else if((opt=="Down") || (opt=="Down-Left") || (opt=="Down-Right"))
{
flag=true;
++now_x;
opt=query();
}
else
{
if(now_y==8)
{
flag=true;
++now_x;
}
else
++now_y;
opt=query();
}
}
return;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
solve();
return 0;
}