我爱崔老师系列之 新学的位运算枚举~ HDU4462 scaring the birds 杭州现场赛J题,枚举。
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4462
当时比赛的时候读错题意了。。。很悲催的没有考虑n*n个稻草人的时候。。。。然后一直WA= =。。。悲剧啊。。。。
回来的时候崔老师教了一个枚举的办法。。。就是位运算。。之前做的一道DFS也可以用位运算来写(其实取1或者取0的dfs都可以用位运算写= =)~、
膜拜崔老师~
View Code
#include <iostream> #include <math.h> #include <stdio.h> #include <string.h> #include <stdlib.h> int map[55][55]; int hash[55][55],count,n; using namespace std; struct node { int x,y,r; }scare[15]; int top,q[100],ans,leap; int judge() { int i,j; for(i = 1;i <= n;i++) { for(j = 1;j <= n;j++) { if(!hash[i][j]&&map[i][j] == 0) return 0; } } return 1; } void reverse(int t) { int i,j,x1,x2,y1,y2; x1 = scare[t].x-scare[t].r; x2 = scare[t].x+scare[t].r; y1 = scare[t].y-scare[t].r; y2 = scare[t].y+scare[t].r; if(x1 < 1)//防止数组越界 x1 = 1; if(y1 < 1) y1 = 1; if(x2 > n) x2 = n; if(y2 > n) y2 = n; for(i = x1;i <= x2;i++)//在那个方格中找 { for(j = y1;j <= y2;j++) { if(abs(i-scare[t].x)+abs(j-scare[t].y) <= scare[t].r && hash[i][j] != 1) map[i][j] = 1; } } } void recover(int t) { int i,j,x1,x2,y1,y2; x1 = scare[t].x-scare[t].r; x2 = scare[t].x+scare[t].r; y1 = scare[t].y-scare[t].r; y2 = scare[t].y+scare[t].r; if(x1 < 1)//防止数组越界 x1 = 1; if(y1 < 1) y1 = 1; if(x2 > n) x2 = n; if(y2 > n) y2 = n; for(i = x1;i <= x2;i++) { for(j = y1;j <= y2;j++) { if(abs(i-scare[t].x)+abs(j-scare[t].y) <= scare[t].r && hash[i][j] != 1) map[i][j] = 0; } } } int main() { int m,i,j; while(scanf("%d",&n)&&n) { leap = 0; memset(map,0,sizeof(map)); memset(hash,0,sizeof(hash)); cin>>m; ans = 1000; for(i = 0;i < m;i++) { scanf("%d %d",&scare[i].x,&scare[i].y); hash[scare[i].x][scare[i].y] = 1;//把稻草人的地方标记一下,省的找了。。。稻草人本来就是空地不用考虑上不上色、 } for(i = 0;i < m;i++) { cin>>scare[i].r; } if(n*n == m) { cout<<"0"<<endl; continue; } for(i = 0;i < (1<<m);i++) { count = top = 0; for(j = 0;j < m;j++) { if((1<<j)&i)//第J个在i情况中用到。 { count++; reverse(j); q[top++] = j; } } if(judge()) { if(ans > count) ans = count; leap = 1; } while(top > -1) { recover(q[--top]); } } if(leap) cout<<ans<<endl; else puts("-1"); } return 0; }
1 #include<stdio.h> 2 #include<string.h> 3 char map[205][205]; 4 struct node 5 { 6 int x,y,step,f;//f存先驱,step是当前的步数。 7 }q[400005]; 8 9 int way[400005];//用来最后存路径 10 int f,r,m,n,fa,leap; 11 int vis[205][205]; 12 int to[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};//四个方向 13 void sort()//优先队列排序 14 { 15 int i; 16 struct node t; 17 for(i = r;i > f;i--) 18 { 19 if(q[i].step < q[i-1].step) 20 { 21 t = q[i]; 22 q[i] =q[i-1]; 23 q[i-1] = t; 24 } 25 else 26 break; 27 } 28 } 29 void bfs() 30 { 31 int i,j,nx,ny; 32 memset(vis,0,sizeof(vis)); 33 f = r = 0; 34 leap = 0; 35 q[r].x = 0; 36 q[r].y = 0; 37 if(map[0][0] == 'X')//看看开头能不能走 38 leap = 0; 39 else 40 { 41 42 if(map[0][0] != '.'&& map[0][0] != 'X')//如果是数字的话开头是不能直接将STEP = 0 的。 43 q[r].step = map[0][0]-'0'; 44 else 45 q[r].step = 0; 46 q[r].f = -1; 47 vis[0][0] = 1; 48 r++; 49 while(f < r) 50 { 51 struct node now; 52 fa = f; 53 now = q[f++]; 54 for(i = 0;i < 4;i++) 55 { 56 nx = now.x+to[i][0]; 57 ny = now.y+to[i][1]; 58 59 if(nx >= 0 && nx < m && ny >= 0 && ny < n && map[nx][ny] != 'X' && !vis[nx][ny]) 60 { 61 q[r].x = nx; 62 q[r].y = ny; 63 64 q[r].f = fa; 65 if(map[nx][ny] == '.') 66 q[r].step = now.step+1; 67 else 68 q[r].step = map[nx][ny]-'0'+now.step + 1; 69 70 if(nx == m-1 && ny == n-1) 71 { 72 leap = 1; 73 break; 74 } 75 sort();//优先队列排序。。。这里一定不要加错位置、 76 r++; 77 vis[nx][ny] = 1; 78 } 79 } 80 if(leap) 81 break; 82 } 83 } 84 } 85 int main() 86 { 87 88 89 90 int i,count,j,nt; 91 while(~scanf("%d %d",&m,&n)) 92 { 93 if(!(m||n)) 94 break; 95 memset(map,0,sizeof(map)); 96 for(i = 0;i < m;i++) 97 scanf("%s",map[i]); 98 bfs(); 99 if(leap) 100 { 101 printf("It takes %d seconds to reach the target position, let me show you the way.\n",q[r].step); 102 count = -1; 103 while(1) 104 { 105 way[++count] = r; 106 r = q[r].f; 107 if(r == -1) 108 break; 109 } 110 nt = 1; 111 for(i = count;i > 0;i--) 112 { 113 printf("%ds:(%d,%d)->(%d,%d)\n",nt++,q[way[i]].x,q[way[i]].y,q[way[i-1]].x,q[way[i-1]].y); 114 if(map[q[way[i-1]].x][q[way[i-1]].y] != '.' ) 115 { 116 int time; 117 time = map[q[way[i-1]].x][q[way[i-1]].y]-'0'; 118 for(j = 0;j < time;j++) 119 { 120 printf("%ds:FIGHT AT (%d,%d)\n",nt++,q[way[i-1]].x,q[way[i-1]].y); 121 } 122 } 123 } 124 125 } 126 else 127 puts("God please help our poor hero."); 128 puts("FINISH"); 129 } 130 return 0; 131 }