Title:
Here's a picture for you. "Chen" stands for the wall, and ".." stands for walking. Now we need to place cannons on "..", and we can't put any more cannons on the top, bottom, left and right of the points where cannons are placed, unless there are walls separated. Ask how many such points can be put at most.
Explanation:
This problem can be done with DFS and bipartite graph, DFS.. Feel like a mental retardation, simple DFS can not write out, clearly BFS so skilled.. Why do you look like a fool when you arrive at DFS. The DFS of this question is similar to the question of eight queens.. Let's talk about the bipartite chart.
How to make a bipartite picture? If the relationship between rows and columns is'. ', it means that there is a relationship between them. Then the Hungarian algorithm can pass, and it's difficult to build a graph at a reduced point. Get two block two-dimensional arrays, corresponding to rows and columns respectively, and then how to represent a point without 'ා' is OK. See my code for specific operation.
Bipartite graph:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN=50; char s[MAXN][MAXN]; bool vis[MAXN]; bool map[MAXN][MAXN]; int block1[MAXN][MAXN],block2[MAXN][MAXN]; int cx[MAXN],cy[MAXN]; int n,x1,y1; void build() { x1=1,y1=1; for(int i=0;i<n;i++)//That's ok { for(int j=0;j<n;j++) if(s[i][j]=='X') x1++; else block1[i][j]=x1; x1++;//In this case, there may be a result of X1 + + in the last column, and there is also a result of X1 + +, which results in an increase of 1 in x1, but it has no effect, because there is no other relationship between the extra number and its construction, but it needs to be a reduction point. } // printf("x1 =%d\n",x1); for(int j=0;j<n;j++)//column { for(int i=0;i<n;i++) if(s[i][j]=='X') y1++; else block2[i][j]=y1; y1++; } for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(s[i][j]=='.') map[block1[i][j]][block2[i][j]]=true; } int dfs(int u) { for(int v=1;v<y1;v++) { if(map[u][v]&&!vis[v]) { vis[v]=true; if(cy[v]==-1||dfs(cy[v])) { cx[u]=v; cy[v]=u; return 1; } } } return 0; } int main() { while(~scanf("%d",&n),n) { memset(map,false,sizeof(map)); memset(cx,-1,sizeof(cx)); memset(cy,-1,sizeof(cy)); memset(block1,0,sizeof(block1)); memset(block2,0,sizeof(block2)); for(int i=0;i<n;i++) scanf("%s",&s[i]); build(); int ans=0; for(int i=1;i<x1;i++) { memset(vis,false,sizeof(vis)); ans+=dfs(i); } printf("%d\n",ans); } }
DFS:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN=15; char s[MAXN][MAXN]; bool map[MAXN][MAXN]; int n,ans; bool flag; bool check(int x,int y) { if(s[x][y]=='X'||map[x][y]) return false; for(int i=x;i>=0;i--){ if(map[i][y]) return false; if(s[i][y]=='X') break; } for(int i=x;i<n;i++){ if(map[i][y]) return false; if(s[i][y]=='X') break; } for(int i=y;i>=0;i--){ if(map[x][i]) return false; if(s[x][i]=='X') break; } for(int i=y;i<n;i++){ if(map[x][i]) return false; if(s[x][i]=='X') break; } return true; } void dfs(int x,int num) { if(num>ans) ans=num; // printf("%d %d %d\n",x,num,ans); if(x==n*n) return ; int x1=x/n; int y1=x%n; if(check(x1,y1)) { map[x1][y1]=true; dfs(x+1,num+1); map[x1][y1]=false; } dfs(x+1,num); } int main() { while(~scanf("%d",&n)) { if(n==0) break; ans=0; memset(map,false,sizeof(map)); for(int i=0;i<n;i++) scanf("%s",s[i]); dfs(0,0); printf("%d\n",ans); } }