UPC5902/mcpc2017 Honey Heist(bfs+模拟)
题目链接:http://exam.upc.edu.cn/problem.php?cid=1287&pid=4
题意:给一边长为r的正六边形网格,网格中会有障碍,问能否在N步内从a格走到b格。
思考:显然搜索,比较麻烦的是如何在六边形网格中找到与一个格子相邻的六个格子。我的方法是吧六边形网格放到一个二维的数组里,然后通过二分查找找到x所在的行h,再找到x所在的列pos,通过比较h上一行的数字个数和h下一行的数字个数来判断哪些格子和x相邻。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int r,n,a,b,x; 4 pair<int,int> now,ne; 5 int m[2000]; 6 bool flag=0; 7 int lin[20]; 8 int ans; 9 int mp[30]; 10 int M[2000][2000]; 11 int dx[]= {-1,-1,0,1,1,0}; 12 int dy1[]={-1,0,1,1,0,-1}; 13 int dy2[]={-1,0,1,0,-1,-1}; 14 int dy3[]={0,1,1,0,-1,-1}; 15 int vis[2300]; 16 void mov(int x) 17 { 18 int t; 19 int h=lower_bound(mp+1,mp+1+2*r-1,x)-mp;///这个数在h行 20 int pos=x-mp[h-1]; 21 int up=mp[h-1]-mp[h-2]; 22 int dow=mp[h+1]-mp[h]; 23 if(up<dow)t=1; 24 else if(up==dow)t=2; 25 else t=3; 26 for(int i=0; i<6; ++i) 27 { 28 if(t==1) 29 lin[i]=M[h+dx[i]][pos+dy1[i]]; 30 else if(t==2) 31 lin[i]=M[h+dx[i]][pos+dy2[i]]; 32 else lin[i]=M[h+dx[i]][pos+dy3[i]]; 33 } 34 } 35 void bfs() 36 { 37 queue<pair<int,int> >q; 38 now.first=a; 39 now.second=0; 40 q.push(now); 41 while(!q.empty()) 42 { 43 now=q.front(); 44 q.pop(); 45 if(now.second>n)return; 46 if(now.first==b) 47 { 48 flag=1; 49 ans=now.second; 50 return; 51 } 52 53 mov(now.first); 54 for(int i=0; i<6; ++i) 55 { 56 if(lin[i]>0&&m[lin[i]]==0&&(!vis[lin[i]])) 57 { 58 vis[lin[i]]=1; 59 q.emplace(lin[i],now.second+1); 60 } 61 } 62 } 63 } 64 int main() 65 { 66 // freopen("in.txt","r",stdin); 67 scanf("%d%d%d%d%d",&r,&n,&a,&b,&x); 68 for(int i=1; i<=x; ++i) 69 { 70 int t; 71 scanf("%d",&t); 72 m[t]=1; 73 } 74 mp[1]=r; 75 for(int i=2; i<=r; ++i) 76 mp[i]=2*mp[i-1]-mp[i-2]+1; 77 for(int i=r+1; i<=2*r-1; ++i) 78 mp[i]=2*mp[i-1]-mp[i-2]-1; 79 for(int i=1; i<=r*2-1; ++i) 80 { 81 for(int j=1; j<=mp[i]-mp[i-1]; ++j) 82 { 83 M[i][j]=mp[i-1]+j; 84 } 85 } 86 bfs(); 87 if(flag)printf("%d\n",ans); 88 else printf("No\n"); 89 return 0; 90 }