弱菜的做法,生成所有子集,然后从集合元素个数少的开始判断。
有一个大坑是,所有的格子都是空地,这种情况下不用放,输出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 }