題解 CF193A 【Cutting Figure】
阿新 • • 發佈:2020-08-03
思路:搜尋
首先我們知道,最多隻需要刪兩個點,即可滿足要求。
我們所要做的就是看看能不能少刪一個點。
那怎麼判斷呢?
就是先把這個點標為已訪問過,然後另找一個塗了色的點開始搜尋,如果能搜過一遍後,還有沒有訪問過的點,那原先這個點肯定就是所謂的 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; } }