Robots at Warehouse
题目链接: J - Robots at Warehouse Gym - 100971J
题意
在一个N*M的图中,’.’ 代表可以走的路,’1’代表第一个物体,’2’代表第二个物体,’#’代表墙,问你两个物体能不能交换地方。
思路
我原先想的是在两种之间找一条路,判断路上会不会出现度为三的点,只要有度为三的点,那么是一定可以到达的,但其实不只是中间的路,所有的点,包括1和2的位置都是可以判断的。
From every free cell it’s possible to reach every other free cell by moving only through the cells sharing a side.
这句话,非常有用,就是两者之间,必定有路,只需判断这些路中有无度为三的点,但还有一种特例,就是一个环,把两者相连接起来,这种在特判一下即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
#define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define mp make_pair
typedef double db;
typedef long long ll;
const int MAXN = (int)2e5+7;
const int INF = (int)0x3f3f3f3f;
int N,M;
char pic[MAXN];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int cor(int x,int y){
return ((x-1)*M+y);
}
int main()
{
scanf("%d %d",&N,&M);
rep(i,1,N) {
scanf("%s",pic+1+(i-1)*M);
}
int flag = 0;
rep(i,1,N) {
rep(j,1,M){
int id = cor(i,j);
if (pic[id] != '#'){
int cnt = 0;
rep(k,0,3){
int dx = dir[k][1] + i;
int dy = dir[k][0] + j;
if (dx < 1 || dx > N || dy < 1 || dy > M) continue;
int d = cor(dx,dy);
if (pic[d] != '#') cnt ++;
}
if (cnt >= 3) return 0*puts("YES");
if (cnt <= 1) flag = 1;
}
}
}
if (flag) puts("NO");
else puts("YES");
}