简单枚举所有子集,再根据子集判断。
代码如下 :
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 typedef struct{ 7 int x,y; 8 }POINT; 9 10 POINT p[20]; 11 12 int n, K, range[20], ans, loc; 13 14 int abs(int x) { return x>0?x:-x; } 15 16 int main() 17 { 18 // freopen("in.txt", "r", stdin); 19 20 while(scanf("%d", &n)!=EOF && n) 21 { 22 scanf("%d", &K); 23 for(int i=0; i<K; i++){ 24 scanf("%d%d", &p[i].x, &p[i].y); 25 } 26 for(int i=0; i<K; i++){ 27 scanf("%d", &range[i]); 28 } 29 int num = (1<<K), vis[10], Map[100][100]; 30 ans = 11; 31 for(int l=0; l<num; l++){ 32 memset(Map, 0, sizeof Map); 33 for(int i=0; i<K; i++){ 34 Map[p[i].x][p[i].y] = 1; 35 } 36 loc = 0; 37 for(int i=0; i<K; i++){ 38 vis[i] = ((l&(1<<i))==0?0:1); 39 loc += vis[i]; 40 } 41 42 for(int i=1; i<=n; i++){ 43 for(int j=1; j<=n; j++){ 44 for(int k=0; k<K; k++){ 45 if((abs(i-p[k].x)+abs(j-p[k].y))<=range[k] && vis[k]) Map[i][j] = 1; 46 } 47 } 48 } 49 int flag = 1; 50 for(int i=1; i<=n; i++){ 51 for(int j=1; j<=n; j++){ 52 if(Map[i][j]==0){ 53 flag = 0; 54 break; 55 } 56 } 57 } 58 if(flag)ans = min(ans, loc); 59 } 60 if(ans==11) printf("-1\n"); 61 else printf("%d\n", ans); 62 } 63 return 0; 64 }