HDU 4462 Scaring the Birds(2012年杭州赛区现场赛J题)

弱菜的做法,生成所有子集,然后从集合元素个数少的开始判断。

有一个大坑是,所有的格子都是空地,这种情况下不用放,输出0。

 

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 using namespace std;
  6 struct sub{
  7     int u;
  8     int v;
  9     int w;
 10 }q[2001];
 11 
 12 struct node{
 13     int b[2001];
 14     int num;
 15     bool friend operator <(node a, node b){
 16         return a.num < b.num;
 17     }
 18 }p[2001];
 19 
 20 int map[101][101];
 21 int n,k;
 22 int j=0;
 23 
 24 void subset(int n, int *a, int cur){
 25     int i;
 26     for(i=0; i<cur; i++){
 27         p[j].b[i]=a[i];
 28     }
 29     p[j++].num=cur;
 30     int s=cur?a[cur-1]+1:0;
 31     for(i=s; i<n; i++){
 32         a[cur]=i;
 33         subset(n, a, cur+1);
 34     }
 35 }
 36 
 37 void init(){
 38     memset(map, 0, sizeof(map));
 39     for(int i=0; i<k ;i++){
 40         map[q[i].u][q[i].v]=1;
 41     }
 42 }
 43 void color(int x, int y, int w){
 44     for(int i=0; i<=w; i++){
 45         for(int j=w-i; j>=0; j--){
 46             if(y+j<n&&x+i<n)
 47             map[x+i][y+j]=1;
 48             if(y-j>=0&&x+i<n)
 49             map[x+i][y-j]=1;
 50             if(x-i>=0&&y+j<n)
 51             map[x-i][y+j]=1;
 52             if(x-i>=0&&y-j>=0)
 53             map[x-i][y-j]=1;
 54         }
 55     }
 56 }
 57 
 58 bool lv(){
 59     for(int i=0; i<n; i++){
 60         for(int j=0; j<n; j++){
 61             if(map[i][j]==0)
 62                 return false;
 63         }
 64     }
 65     return true;
 66 }
 67 
 68 void solve(){
 69     for(int i=0; i<(1<<k); i++){
 70         init();
 71         for(int j=0; j<p[i].num; j++){
 72             color(q[p[i].b[j]].u, q[p[i].b[j]].v, q[p[i].b[j]].w);
 73         }
 74         bool f=lv();
 75         if(f==true){
 76             cout<<p[i].num<<endl;
 77             return;
 78         }
 79     }
 80     cout<<"-1"<<endl;
 81 }
 82 
 83 int main(){
 84     int x, y;
 85     int a[101];
 86     while(~scanf("%d", &n)){
 87         memset(map,0,sizeof(map));
 88         j=0;
 89         if(n==0)
 90             break;
 91         scanf("%d", &k);
 92         for(int i=0; i<k; i++){
 93             scanf("%d %d", &x, &y);
 94             q[i].u=x-1;
 95             q[i].v=y-1;
 96             a[i]=i;
 97             map[x-1][y-1]=1;
 98         }
 99         for(int i=0; i<k; i++){
100             scanf("%d", &q[i].w);
101         }
102         subset(k, a, 0);
103         sort(p, p+(1<<k));
104         if(lv()){
105             puts("0");
106             continue;
107         }
108         solve();
109     }
110     return 0;
111 }

转载于:https://www.cnblogs.com/pony1993/archive/2012/11/08/2761401.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值