HDU4462 Scaring the Birds 枚举

今年杭州现场赛的简单题,思路早就有了。结果在判断稻草人能够覆盖的范围那块地方用了深搜,结果悲剧一般的TLE了一整场比赛。代码几乎没有改,和带回来的打印稿一对比,几乎没有什么区别,发现现场居然没有尝试些循环,明明n最大就是50。。。还去写了深搜。。脑子似乎是短路了一般,觉得多判断几个范围外的点会影响效率,结果,用DFS去判断之后范围效率低下,也不知道是我写的挫,还是什么情况。。。。T-T 。 其实这题我们队除了我之外另一个人也写过,他那块部分就是用的循环判断不是深搜,而他枚举部分写的有问题,所以也是TLE,其实只要我的枚举部分+上循环覆盖那块就可以A掉了。太生疏了。又是一个教训。

Scaring the Birds

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 372    Accepted Submission(s): 123


Problem Description
It’s harvest season now!
Farmer John plants a lot of corn. There are many birds living around his corn field. These birds keep stealing his corn all the time. John can't stand with that any more. He decides to put some scarecrows in the field to drive the birds away.
John's field can be considered as an N×N grid which has N×N intersections. John plants his corn on every intersection at first. But as time goes by, some corn were destroyed by rats or birds so some vacant intersections were left. Now John wants to put scarecrows on those vacant intersections and he can put at most one scarecrow on one intersection. Because of the landform and the different height of corn, every vacant intersections has a scaring range R meaning that if John put a scarecrow on it, the scarecrow can only scare the birds inside the range of manhattan distance R from the intersection.



The figure above shows a 7×7 field. Assuming that the scaring range of vacant intersection (4,2) is 2, then the corn on the marked intersections can be protected by a scarecrow put on intersection (4,2).
Now John wants to figure out at least how many scarecrows he must buy to protect all his corn.


 

Input
There are several test cases.
For each test case:
The first line is an integer N ( 2 <= N <= 50 ) meaning that John's field is an N×N grid.
The second line is an integer K ( 0<= K <= 10) meaning that there are K vacant intersections on which John can put a scarecrow.
The third line describes the position of K vacant intersections, in the format of r 1,c 1,r 2,c 2 …. r K,c k . (r i,c i) is the position of the i-th intersection and 1 <= r 1,c 1,r 2,c 2 …. r K,c k <= N.
The forth line gives the scaring range of all vacant intersections, in the format of R 1,R 2…R K and 0 <= R 1,R 2…R K <= 2 × N.
The input ends with N = 0.


 

Output
For each test case, print the minimum number of scarecrows farmer John must buy in a line. If John has no way to protect all the corn, print -1 instead.


 

Sample Input
  
  
4 2 2 2 3 3 1 3 4 2 2 2 3 3 1 4 0


 

Sample Output
  
  
-1 1

 

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;


#define MAXN 60

bool flag;
int n,m;
int x[20],y[20],r[20];
int map[MAXN][MAXN];
int node[MAXN],total;

void func()
{
  int L,R,T,D;
  memset(map,0,sizeof(map));
  for(int i=1;i<=m;i++)
    map[x[i]][y[i]]=1;
  for(int i=0;i<total;i++)
  {
    int k=node[i]; 
    L=(x[k]-r[k]>0?x[k]-r[k]:1);
    R=(x[k]+r[k]<=n?x[k]+r[k]:n);
    T=(y[k]-r[k]>0?y[k]-r[k]:1);
    D=(y[k]+r[k]<=n?y[k]+r[k]:n);
    for(int j=L;j<=R;j++)
      for(int l=T;l<=D;l++)
        if(abs(j-x[k])+abs(l-y[k])<=r[k])
          map[j][l]=1;
  }
  for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
      if(!map[i][j]) return;
  flag=1;
}

void dfs(int sel,int cnt)
{
  if(sel==total)
    func();
  else
    for(int i=cnt;i<=m;i++)
    {
      node[sel]=i;
      dfs(sel+1,i+1);
    }
}

void solve()
{
  scanf("%d",&m);
  for(int i=1;i<=m;i++)
    scanf("%d%d",&x[i],&y[i]);
  for(int i=1;i<=m;i++)
    scanf("%d",&r[i]);
  flag=0;
  if(m>=n*n)
  {
    printf("0\n");
    return;
  }
  for(int i=1;i<=m;i++)
  {
    total=i;
    dfs(0,1);
    if(flag==1)
    {
      printf("%d\n",i);
      return;
    }
  }
  printf("-1\n");
    
}

int main()
{
  while(~scanf("%d",&n) && n)
    solve();
  return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值