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 } 
二分图

 

posted @ 2021-01-23 12:07  acmloser  阅读(33)  评论(0编辑  收藏  举报