J. Robots at Warehouse
time limit per test
2.0 s
memory limit per test
256 MB
input
standard input
output
standard output
Vitaly works at the warehouse. The warehouse can be represented as a grid of n × m cells, each of which either is free or is occupied by a container. From every free cell it's possible to reach every other free cell by moving only through the cells sharing a side. Besides that, there are two robots in the warehouse. The robots are located in different free cells.
Vitaly wants to swap the robots. Robots can move only through free cells sharing a side, moreover, they can't be in the same cell at the same time or move through each other. Find out if the swap can be done.
Input
The first line contains two positive integers n and m (2 ≤ n·m ≤ 200000) — the sizes of the warehouse.
Each of the next n lines contains m characters. The j-th character of the i-th line is «.» if the corresponding cell is free, «#» if there is a container on it, «1» if it's occupied by the first robot, and «2» if it's occupied by the second robot. The characters «1» and «2» appear exactly once in these lines.
Output
Output «YES» (without quotes) if the robots can be swapped, and «NO» (without quotes) if that can't be done.
Examples
input
Copy
5 3 ### #1# #.# #2# ###
output
Copy
NO
input
Copy
3 5 #...# #1.2# #####
output
Copy
YES
题意:输入n,m 表示 n * m 的矩阵,#表示墙, 。 表示路,1 , 2 表示两个机器人,问1 , 2 机器人能不能交换位置,1 2机器人不能在同一个点,1, 2相邻的时候不能交换位置,而且点都是连在一起的(看其他人博客的时候发现的)
思路:其实1 , 2 两个机器人换位置就有可能两种可能,要不就是有1 2机器人之间两条路(有环),要不就是路上有T字型的路口,因为这样其中一个机器人可以藏在分支上,另个一个机器人就可以通过这里
如果是有环,那么矩阵中的点的旁边都是有两个点的,比如
# # # # #
#。#。#
# 1 # 2 #
#。#。#
# # # # #
像题目中的样例 1 就是有两个点旁边没有两个点的(1 , 2机器人的点),这样可以判断输出NO
T型路口的,只要是有一个这样的存在就可以输出YES,我们可以直接暴力遍历所有点,只要有一个点周围有三个点,就可以输出YES,比如
# # # # #
# #。# #
1 。。。2
# # # # #
在map[ 3 ] [ 3 ]的点的周围有三个点,所以可以判断能交换位置
坑点:主要是点都是连在一起的,所以少了很多麻烦,网上有人就是BFS搜索路然后回溯查找有没有T型路口,然后再用DFS搜索有没有环,这样就超时了
AC代码:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
int n,m,i,j;
bool flag=true; //一开始设立为true,有环的可能
cin>>n>>m;
int ans=0;
vector<string> map(n);
for (i=0;i<n;i++)
cin>>map[i];
for (i=0;i<n;i++)
for (j=0;j<m;j++)
{
ans=0; //判断一个点周围有多少点
if (map[i][j]=='#')
continue;
if (i!=0&&map[i-1][j]!='#') //注意边界, 1 , 2机器人一开始的地方也可以走,所以可以看成点
ans++;
if (i!=n-1&&map[i+1][j]!='#')
ans++;
if (j!=0&&map[i][j-1]!='#')
ans++;
if (j!=m-1&&map[i][j+1]!='#')
ans++;
if (ans>=3) //有三个点直接输出
{
cout<<"YES"<<endl;
return 0;
}
if (ans==1) //当有一个点周围只有一个点,说明是死路,如果所有点都没有其他情况,就可以输出NO
flag=false;
}
if (flag) //有环的存在没有一个点周围是两个点的,如果有那也是T型路口的情况
cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}