思路:搜索
首先我们知道,最多只需要删两个点,即可满足要求。
我们所要做的就是看看能不能少删一个点。
那怎么判断呢?
就是先把这个点标为已访问过,然后另找一个涂了色的点开始搜索,如果能搜过一遍后,还有没有访问过的点,那原先这个点肯定就是所谓的 solo 之王单一解答案了。
那么我们读入数据,同时标注哪些点已经涂过色,然后在每个已经涂过点的基础上求解,如果这个涂色点能够满足单一解,那就输出 1 ,否则就输出 2 。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define F first
#define S second
using namespace std;
const int N=55;
const int dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1};
bool map[N][N],vis[N][N];
int n,m,num;
vector< pair<int,int> > v;
void dfs(int x,int y) {//搜索
vis[x][y]=1;
for(int i=1;i<=4;i++) {
int xx=x+dx[i],yy=y+dy[i];
if(!vis[xx][yy]&&map[xx][yy]) dfs(xx,yy);
}
}
bool solve(int x,int y) {//求单一解
bool opt=0;
memset(vis,0,sizeof(vis));
vis[x][y]=1;
for(int i=0;i<v.size();i++) {
if(!vis[v[i].F][v[i].S]) {
if(opt) return 1;
opt=1;
dfs(v[i].F,v[i].S);
}
}
return 0;
}
int main() {
char ch;
cin>>n>>m;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
cin>>ch;
if(ch-'.') {
map[i][j]=1;
num++;
v.push_back(make_pair(i,j));
}
}
}
if(num<=2) puts("-1");//涂色点总数小于2特判无解
else {
for(int i=0;i<v.size();i++) {
if(solve(v[i].F,v[i].S)) {//求单一解
puts("1");
return 0;
}
}
puts("2");
return 0;
}
}