[USACO13OPEN]重力异常
题目描述
船长正在拯救她的船员,Beefalo 博士。
和所有伟大的冒险故事一样,这个故事也是发生在一个2D平面上的。囧
这个平面是M*N的格子组成的网格,代表着船长的世界的一个侧视图。
有些格子是空的,另一些则是实心的,并且不能直接通过。
很不幸的是,船长跳不起来。她必须遵守这个世界的特殊物理法则。
1)如果船长的正下方没有方块(换句话说,即使她正在网格的边缘),那么她就会掉入宇宙中,同时意味着冒险失败。
2)如果船长的正下方的方块是空的,那么她就会掉到这个方块,
3)在不满足1)与2)的情况下,船长可以做一下的事情:
a) 如果左边(或右边)的方格是空的,那么她可以走到那个格子。
b船长可以翻转重力的方向
当船长改变翻转重力的方向时,我们就改变船长”下方“的定义。
”下方“的定义只能是两种
(A)比船长位置所在的方格的列编号更大的格子,
(B)比船长位置所在的方格的列编号更小的格子,
一开始的时候,“下方”的定义是比船长位置所在方格的列编号更大的格子。
Beefalo博士正迷失在这个世界中的某一处,请帮助船长从起点到达博士的地方。
如果可以到达,请输出最少需要的翻转重力的次数。
如果不可以到达,请输出-1
输入
第1行输入两个整数 N,M
第2行到N+1行中,第i+1行则是代表船长世界的第i行。每行有M个字符。
其中","代表着一个空的格子,"#"代表着一个实心的格子,"C"代表着船长的位置,"D"代表着博士的位置。
输出
一行,输出一个整数。
如果船长可以到达,请输出最少需要的翻转重力的次数。
如果不可以到达,请输出-1
样例输入
样例输出
提示
输出解释
首先,船长在(4,2),接着她翻转重力,到达(2,2)
接着她向右走走到(2,4),接着她第二次翻转重力,到达(4,4)
然后她继续向右走到(4,5),最后在翻转一次重力,到达博士所在的(3,5)
搜索,因为数据较大,用优先队列优化。
重点是“掉落”操作,但也不难,注意细节,到达终点直接输出。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #include<iostream> 6 using namespace std; 7 struct Messi 8 { 9 int x,y,s; 10 bool b; 11 bool operator<(const Messi& rhs) const 12 { 13 return s>rhs.s; 14 } 15 } c; 16 priority_queue<Messi> q; 17 int xs,ys,xe,ye,n,m,f[1001][1001],vis[1001][1001][2]; 18 void G(int x,int y) 19 { 20 int xx=x,b=0; 21 if (c.b==0) 22 { 23 while (xx<=n&&f[xx+1][y]) xx++; 24 if (xx<n&&vis[xx][y][0]==0) 25 vis[xx][y][0]=1,q.push((Messi){xx,y,c.s,0}); 26 } 27 else 28 { 29 while (xx>=1&&f[xx-1][y]) xx--; 30 if (xx>1&&vis[xx][y][1]==0) 31 vis[xx][y][1]=1,q.push((Messi){xx,y,c.s,1}); 32 } 33 if (y==ye) 34 { 35 if ((c.b==1&&xx<=xe&&x>=xe)||(c.b==0&&xx>=xe&&x<=xe)) 36 { 37 cout<<c.s; 38 exit(0); 39 } 40 } 41 } 42 int main() 43 {int i,j; 44 char ch; 45 cin>>n>>m; 46 for (i=1; i<=n; i++) 47 for (j=1; j<=m; j++) 48 { 49 cin>>ch; 50 if (ch=='#') 51 f[i][j]=0; 52 if (ch=='C') 53 {f[i][j]=1; 54 xs=i; 55 ys=j; 56 } 57 if (ch=='D') 58 {f[i][j]=1; 59 xe=i; 60 ye=j; 61 } 62 if (ch=='.') 63 f[i][j]=1; 64 } 65 c.b=0; 66 c.s=0; 67 G(xs,ys); 68 while (q.empty()==0) 69 { 70 c=q.top(); 71 q.pop(); 72 //cout<<c.x<<' '<<c.y<<' '<<c.b<<' '<<c.s<<endl; 73 if (c.x==xe&&c.y==ye) 74 { 75 cout<<c.s; 76 return 0; 77 } 78 if (c.y-1>=1&&f[c.x][c.y-1]) 79 G(c.x,c.y-1); 80 if (c.y+1<=m&&f[c.x][c.y+1]) 81 G(c.x,c.y+1); 82 c.b=(c.b==0); 83 c.s+=1; 84 G(c.x,c.y); 85 } 86 cout<<-1; 87 }