hdu 4462 第37届ACM/ICPC 杭州赛区 J题

题意:有一块n*n的田,田上有一些点可以放置稻草人,再给出一些稻草人,每个稻草人有其覆盖的距离ri,距离为曼哈顿距离,求要覆盖到所有的格子最少需要放置几个稻草人

由于稻草人数量很少,所以状态压缩枚举,之后慢慢判断即可,注意放稻草人的格子是不需要覆盖的

 1 #include<cstdio>

 2 #include<iostream>

 3 #include<algorithm>

 4 #include<cstring>

 5 #include<cmath>

 6 #include<queue>

 7 #include<map>

 8 using namespace std;

 9 #define MOD 1000000007

10 const int INF=0x3f3f3f3f;

11 const double eps=1e-5;

12 #define cl(a) memset(a,0,sizeof(a))

13 #define ts printf("*****\n");

14 const int MAXN=1005;

15 int n,m,tt;

16 int x[MAXN],y[MAXN],r[MAXN],a[MAXN];

17 int main()

18 {

19     int i,j,k;

20     #ifndef ONLINE_JUDGE

21     freopen("1.in","r",stdin);

22     #endif

23     while(scanf("%d",&n)!=EOF)

24     {

25         if(n==0)    break;

26         scanf("%d",&k);

27         for(i=0;i<k;i++)    scanf("%d%d",&x[i],&y[i]);

28         for(i=0;i<k;i++)    scanf("%d",&r[i]);

29         int bit=(1<<k)-1;

30         int ans=1000000;

31         for(int s=0;s<=bit;s++)

32         {

33             int num=0;

34             for(j=0;j<k;j++)

35             {

36                 if(s&(1<<j))

37                 {

38                     a[num++]=j; //记录有放稻草人的格子

39                 }

40             }

41             bool vis[MAXN][MAXN],flag=1;

42             cl(vis);

43             for(i=1;i<=n;i++)

44             {

45                 for(j=1;j<=n;j++)

46                 {

47                     for(int d=0;d<k;d++)    //没放稻草人的格子

48                     {

49                         if(i==x[d]&&j==y[d])    vis[i][j]=1;

50                     }

51                     for(int d=0;d<num;d++)

52                     {

53                         if(fabs(i-x[a[d]])+fabs(j-y[a[d]])<=r[a[d]])    //曼哈顿距离

54                         {

55                             vis[i][j]=1;

56                             break;

57                         }

58                     }

59                     if(vis[i][j]==0)  //说明所有稻草人没法覆盖,该状态方案不可行

60                         flag=0;

61                 }

62                 if(flag==0) break;  //说明所有稻草人没法覆盖,该状态方案不可行

63             }

64             if(!flag)continue;

65             ans=min(ans,num);

66         }

67         if(ans>100000)ans=-1;

68         printf("%d\n",ans);

69     }

70 }

 

你可能感兴趣的:(ICPC)