1 条题解
-
0
国际象棋一步将死问题题解
题目分析
题目要求判断是否存在一步移动白后即可将死黑王的走法。将死的条件是:
. 黑王当前处于被攻击状态(将军)。
. 黑王无法通过任何合法移动(个相邻格子)逃脱攻击(所有可能的移动位置均被白方控制或越界)。算法思路
. 输入处理:将输入的位置(如)转换为棋盘坐标(,),其中为-(对应-),为-(对应-)。
. 枚举白后的所有合法移动:白后可沿个方向(上下左右、个对角线)移动任意格,但路径不能穿过白王或黑王的位置。
. 检查将死条件:对每个白后的目标位置,判断是否满足:- 黑王被白后攻击(同一行/列/对角线)。
- 黑王的所有可能移动位置(个相邻格子)均被白王或白后攻击,或越界。
. 选择最优解:若存在多个将死位置,选择列最小(最小)、行最小(最小)的位置。
代码关键细节解释
. 方向数组
int dx[9]={0,0,1,-1,1,1,-1,-1,0}; int dy[9]={1,-1,0,0,1,-1,1,-1,0};
和表示王的种可能移动方向(包括个相邻方向和原地)。但实际王不能留在原地,因此代码中会过滤越界的情况。
. 函数(判断是否将死)
函数逻辑:遍历黑王的所有可能移动位置(个相邻格子),检查每个位置是否被白方控制。
- 对于每个黑王可能的移动位置(,):
- 检查是否被白王攻击:白王的个相邻格子是否覆盖(,)。
- 检查是否被白后攻击:白后的个方向路径上是否覆盖(,)(路径不能穿过白王)。
- 若所有黑王的移动位置均被控制,则当前白后位置是将死位置。
. 枚举白后的移动路径
白后沿个方向移动,每个方向枚举所有可能的终点(直到越界或被白王/黑王阻挡):
for(int i=0;i<8;i++) { // 8个方向 for(int j=1;;j++) { // 沿当前方向移动j步 int x=wqx+dx[i]*j; int y=wqy+dy[i]*j; if(x<1||x>8||y<1||y>8) break; // 越界 if(x==wkx && y==wky) break; // 被白王阻挡 if(x==bkx && y==bky) break; // 被黑王阻挡 // 检查当前(x,y)是否能将死 if(check(x,y)) { // 记录最优解(x最小,y最小) } } }
. 最优解选择
遍历所有可能的将死位置,选择列最小(最小)、行最小(最小)的位置。
示例分析(输入 )
- 白王位置(,),白后位置(,),黑王位置(,)。
- 白后移动到(,):
- 白后与黑王在同一列(),形成将军。
- 黑王的可能移动位置为:
- (,):被白后占据(攻击)。
- (,):被白王(,的相邻格子包括 (,),(,)等,但 (,)是否被白王攻击?需计算白王的个相邻格子是否覆盖 (,)。
- 其他位置可能越界或被白后攻击。
- 所有移动位置均被控制,因此是将死位置。
总结
本题核心是枚举白后的所有合法移动,并验证每个位置是否满足将死条件。关键在于正确实现将死的判断逻辑(黑王的所有移动均被控制),以及白后移动路径的合法性检查(不穿过其他棋子)。通过方向数组和循环枚举,确保覆盖所有可能的情况。
代码如下:
#include <iostream> #include <cstdio> #include <string> int wqx,wqy,wkx,wky,bkx,bky; using namespace std; //英语 看博友分析 抄博友程序 int dx[9]={0,0,1,-1,1,1,-1,-1,0}; int dy[9]={1,-1,0,0,1,-1,1,-1,0}; bool check(int x,int y) { //cout<<"check "<<x<<" "<<y<<endl; bool flag=true; for(int i=0;i<9;i++) { int bx=bkx+dx[i]; int by=bky+dy[i]; //cout<<bx<<" "<<by<<endl; if(bx<1 || bx>8 || by<1 ||by>8) { continue; } bool f=false; for(int j=0;j<8;j++)//白王 { int tkx=wkx+dx[j]; int tky=wky+dy[j]; if(tkx<1 || tkx>8 || tky<1 || tky>8) { continue; } if(tkx==bx && tky==by) { f=true; } } for(int j=0;j<8;j++)//白后 { for(int k=1;;k++) { int tqx=x+dx[j]*k; int tqy=y+dy[j]*k; if(tqx<1 || tqx>8 || tqy<1 || tqy>8) { break; } if(tqx==wkx && tqy==wky) { break; } if(tqx==bx && tqy==by) { f=true; } } } //cout<<"f "<<f<<endl; if(f==false) { flag=false; } } //cout<<"flag "<<flag<<endl; return flag; } int main() { string wq,wk,bk; cin>>wk>>wq>>bk; wqx=wq[0]-'a'+1; wqy=wq[1]-'0'; wkx=wk[0]-'a'+1; wky=wk[1]-'0'; bkx=bk[0]-'a'+1; bky=bk[1]-'0'; int flag=false; int jx=10; int jy=10; for(int i=0;i<8;i++) { for(int j=1;;j++) { int x=wqx+dx[i]*j; int y=wqy+dy[i]*j; if(x<1||x>8||y<1||y>8) { break; } if(x==wkx && y==wky) { break; } if(x==bkx && y==bky) { break; } if(check(x,y)) { flag=true; if(jx>x) { jx=x; jy=y; }else if(jx==x && jy>y) { jx=x; jy=y; } } } } if(flag==false) { cout<<"no"<<endl; }else { cout<<(char)(jx-1+'a')<<jy<<endl; } return 0; }
- 1
信息
- ID
- 648
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者