ZOJ 1002 Fire Net

给一个4x4的网格图,有一些格子不能放东西,需要在里面放一些车(读音:ju二声)使得互不攻击,求最大放的个数。

(直接爆搜就好了啊喂)

(不妨用一下enum去保存状态。。。可读性更好一些。。。)


  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstdio>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <vector>
  7 
  8 using namespace std;
  9 
 10 int n, ans;
 11 enum{
 12     WALL, PLACE, BLOCKHOUSE, BULLET
 13 }city[5][5];
 14 char s[10];
 15 
 16 bool check(int i, int j){
 17     return city[i][j] == PLACE;
 18 }
 19 
 20 
 21 void f(int i, int j, int step = 0){
 22 
 23     
 24 
 25     if(i == n + 1){
 26         ans = max(ans, step);
 27         return;
 28     }
 29     if(check(i, j)){
 30 
 31         city[i][j] = BLOCKHOUSE;
 32         for(int a = i + 1 ; a <= n ; a ++){
 33             if(city[a][j] == WALL)
 34                 break;
 35             city[a][j] = BULLET;
 36         }
 37         for(int a = i - 1 ; a >= 1 ; a --){
 38             if(city[a][j] == WALL)
 39                 break;
 40             city[a][j] = BULLET;
 41         }
 42         for(int a = j + 1 ; a <= n ; a ++){
 43             if(city[i][a] == WALL)
 44                 break;
 45             city[i][a] = BULLET;
 46         }
 47         for(int a = j - 1 ; a >= 1 ; a --){
 48             if(city[i][a] == WALL)
 49                 break;
 50             city[i][a] = BULLET;
 51         }
 52         
 53 
 54         if(j < n)f(i, j + 1, step + 1);
 55         else f(i + 1, 1, step + 1);
 56 
 57 
 58         //clear
 59         for(int a = i + 1 ; a <= n ; a ++){
 60             if(city[a][j] == WALL)
 61                 break;
 62             city[a][j] = PLACE;
 63         }
 64         for(int a = i - 1 ; a >= 1 ; a --){
 65             if(city[a][j] == WALL)
 66                 break;
 67             city[a][j] = PLACE;
 68         }
 69         for(int a = j + 1 ; a <= n ; a ++){
 70             if(city[i][a] == WALL)
 71                 break;
 72             city[i][a] = PLACE;
 73         }
 74         for(int a = j - 1 ; a >= 1 ; a --){
 75             if(city[i][a] == WALL)
 76                 break;
 77             city[i][a] = PLACE;
 78         }
 79     }
 80     if(j < n)f(i, j + 1, step);
 81     else f(i + 1, 1, step);
 82 }
 83 
 84 int main(){
 85     while(scanf("%d", &n) == 1 && n){
 86         ans = 0;
 87         for(int i = 1 ; i <= n ; i ++){
 88             scanf("%s", s + 1);
 89             for(int j = 1 ; j <= n ; j ++){
 90                 if(s[j] == '.'){
 91                     city[i][j] = PLACE;
 92                 }else{
 93                     city[i][j] = WALL;
 94                 }
 95             }
 96         }
 97         f(1, 1);
 98         printf("%d\n", ans);
 99     }
100 }
View Code

 

你以为这就完了?

不,这道题还可以跑二分图最大匹配(匈牙利算法)

把每一行和每一列都拆成点,行和列有公共点的连一条边,如果中间被格子隔开的话看成两个不相干的行或列(可以用并查集实现)

A集合是行的集合,B集合是列的集合,然后跑二分图最大匹配。

由于每选择一条边意味着该点所在的行和列都被选中了,不能放下别的东西,所以二分图最大匹配就是最大方的个数。

代码?懒得写了。。。

posted @ 2017-08-07 20:42  KingSann  阅读(121)  评论(0编辑  收藏  举报