题解:CF362A Two Semiknights Meet

题意

有两个走法为中国象棋象的棋子,棋盘上有一些坏格子,问它们是否可以在好格子相遇。

思路

则判断两个棋子是否相遇有两个条件

  1. 是否可以在一个格子相遇。
  2. 那个格子是否是好格子。

先考虑条件 \(1\)

设第一个棋子的坐标为 \(a_x\)\(a_y\),第二个棋子的坐标为 \(b_x\)\(b_y\)
则在一盘棋中第二个棋子可以走的地方为
这里设第一个棋子的坐标为 \((1,1)\)

0 12345678
1 K...X...
2 ........
3 ..X...X.
4 ........
5 X...X...
6 ........
7 ..X...X.
8 ........

那么第二个棋子的坐标就应该在图中标了 \(X\) 的位置。
但是实际会比这个更少。
把每个格子到第一个棋子的步数进行标记,得

0 12345678
1 0...2...
2 .\./.\..
3 ..1...3.
4 ./.\./..
5 2...2...
6 .\./.\..
7 ..3...3.
8 ........

奇数格子的棋子下一步到的是偶数格子,偶数格子的棋子的下一步到的是奇数格子,所以要想让两个棋子相遇,则第二个棋子的位置应为偶数标记的格子,就是图中标记为 \(2\) 的格子。
观察图可知,若想使两个棋子都到达同一个位置,那么可得

\[a_x \equiv\ b_x \ (mod \ 4 ) \]

\[a_y\equiv\ b_y \ (mod \ 4) \]

化简,得

\[a_x-b_x \equiv\ 0 \ (mod \ 4 ) \]

\[a_y-b_y \equiv\ 0 \ (mod \ 4 ) \]

所以只要判断两个棋子的 \(x\)\(y\) 坐标相差是否能被 \(4\) 整除就行了。

再来考虑条件 \(2\)

题目中说了,两个棋子最开始的位置一定是个好格子,所以只要让一个棋子来回走一个棋子走到了一个棋子的位置即可。所以本条不用考虑。

AC code

#include<bits/stdc++.h>
using namespace std;
int n,ax,ay,bx,by;
bool first=1;
char ch;
int main(){
	cin>>n;
	while(n--){
		first=1;
		ax=0,ay=0,bx=0,by=0;
		for(int i=1;i<=8;i++){
			for(int j=1;j<=8;j++){
				cin>>ch;
				if(ch=='K'){
					if(first){
						ax=i,ay=j;
						first=0;
					}else{
						bx=i,by=j;
					}
				}
			}
		}
		if((ax-bx)%4||(ay-by)%4) cout<<"NO"<<endl;
		else cout<<"YES"<<endl;
	}
	return 0;
} 
posted @   Laoda_Bryant  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示