Fire Net HDU - 1045
考察:暴力搜索或二分图匹配
暴力搜索的思路:
对地图的每一个位置dfs,如果放炮就要判断该处上下左右有没有其他炮,如果不放就继续搜索
关于判断:我们需要选定一个方向一直走,可以用while,我一开始的思路是bfs标记放了炮的上下左右.这种做法是错的,如果炮在(1,1)按bfs(2,1)会被标记以至于整个第二行都不能放点.
正确的判断是标记放炮的点,上下左右不标记.如果要在某个地方放棋子,就上下左右搜索看是否有标记即可
再注意的是:不放的dfs请放在判断条件外面....
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int N = 6; 6 int n,xx[5] = {-1,1,0,0},yy[5] = {0,0,-1,1},maxn; 7 char mp[N][N]; 8 bool vis[N][N]; 9 bool check(int x,int y) 10 { 11 for(int i=0;i<4;i++) 12 { 13 int dx = x+xx[i],dy=y+yy[i]; 14 while(dx>=0&&dx<n&&dy>=0&&dy<n&&mp[dx][dy]!='X') 15 { 16 if(vis[dx][dy]) return false; 17 dx+=xx[i],dy+=yy[i]; 18 } 19 } 20 return true; 21 } 22 void dfs(int cnt,int i,int j) 23 { 24 if(j==n) i++,j=0; 25 if(i==n) { maxn = max(cnt,maxn); return;} 26 if(check(i,j)&&mp[i][j]!='X') 27 { 28 vis[i][j] = 1; 29 dfs(cnt+1,i,j+1); 30 vis[i][j] = 0; 31 } 32 dfs(cnt,i,j+1);//之前wa的原因是这个dfs应该放外面 33 } 34 int main() 35 { 36 // freopen("in.txt","r",stdin); 37 while(scanf("%d",&n)!=EOF&&n) 38 { 39 for(int i=0;i<n;i++) scanf("%s",mp[i]); 40 memset(vis,0,sizeof vis); 41 maxn = 0; 42 dfs(0,0,0); 43 printf("%d\n",maxn); 44 } 45 return 0; 46 }
二分图匹配:
这个思路是看大佬的,本蒟蒻完全不会
建立二分图,首先要建立两个点集合.在此地图上,我们只能建立行和列的集合.这里需要缩点,也就是将该一行或者一行中墙壁两边设置为一点.(因为大炮只能放在不同行列或者墙壁两边).同理列也需要缩点.给行列缩点集合起好序号.
注意的是mp是点的地方才能建边,否则缩点会多了
再注意的是row和col++的条件(此点为.&&换成了新行或者上一个是X)才++,不能碰到X就++
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <vector> 5 using namespace std; 6 const int N = 7; 7 vector<int> vx,vy; 8 bool g[N][N],st[N*N]; 9 int xx[N][N],yy[N][N],row,col,match[N*N],res,n; 10 char mp[N][N]; 11 void inits() 12 { 13 memset(match,-1,sizeof match); 14 memset(g,0,sizeof g); 15 row = col = 1;res = 0; 16 memset(xx,0,sizeof xx); memset(yy,0,sizeof yy); 17 } 18 bool findw(int x) 19 { 20 for(int i=1;i<=col;i++) 21 { 22 if(g[x][i]&&!st[i]) 23 { 24 st[i] = 1; 25 if(match[i]==-1||findw(match[i])) 26 { 27 match[i] =x; 28 return true; 29 } 30 } 31 } 32 return false; 33 } 34 int main() 35 { 36 while(scanf("%d",&n)!=EOF&&n) 37 { 38 inits(); 39 for(int i=0;i<n;i++) scanf("%s",mp[i]); 40 for(int i=0;i<n;i++) 41 { 42 for(int j=0;j<n;j++) 43 { 44 if(mp[i][j]=='.') 45 { 46 if(!j||mp[i][j-1]=='X') row++; 47 xx[i][j] = row; 48 } 49 if(mp[j][i]=='.') 50 { 51 if(!j||mp[j-1][i]=='X') col++; 52 yy[j][i] = col; 53 } 54 } 55 } 56 for(int i=0;i<n;i++) 57 for(int j=0;j<n;j++) 58 if(mp[i][j]=='.') g[xx[i][j]][yy[i][j]] = 1; 59 for(int i=1;i<=row;i++) 60 { 61 memset(st,0,sizeof st); 62 if(findw(i)) res++; 63 } 64 printf("%d\n",res); 65 } 66 return 0; 67 }