题意:
将(x,y)以四种方式移到棋盘任意一脚 求 最小步数
思路:
数据大不能bfs 四种移动方式可归结为两种 (a,b)和(-a,-b)一类 (a,-b)和(-a,b)一类 然后解方程
x+ak+aj=aimx , y+bk-bj=aimy 解出k和j
但是有解不代表能走 因为可能某一步走出棋盘外 所以还需要判断一下再更新答案
对于x和y方向 总有一个方向是直奔目的地而去的(可以讨论下k和j的正负)
也就是说那一维一定不会走出棋盘 所以关注另一维
我们发现另一维总是前进几步后退几步 所以总可以前进后退磨一磨再直奔目的地
因此只要能迈出第一步就能到达
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; __int64 n,m,x,y,a,b,ans=-1,x0,y0; __int64 func(__int64 fx) { if(fx<0) return -fx; return fx; } int main() { int i; __int64 k,j; while(~scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&n,&m,&x,&y,&a,&b)) { ans=-1; for(i=1;i<=4;i++) { if(i==1) {x0=1; y0=1;} else if(i==2) {x0=1; y0=m;} else if(i==3) {x0=n; y0=1;} else if(i==4) {x0=n; y0=m;} if( (b*x0+a*y0-b*x-a*y)%(a*b*2) == 0 ) { k=(b*x0+a*y0-b*x-a*y)/(a*b*2); if( (x0-a*k-x)%a == 0 ) { j=(x0-a*k-x)/a; if( (x==x0&&y==y0) || (x+a<=n&&y+b<=m) || (x-a>=1&&y-b>=1) || (x+a<=n&&y-b>=1) || (x-a>=1&&y+b<=m) ) { j=func(j); k=func(k); if(ans==-1 || ans> j+k ) ans=j+k; } } } } if(ans!=-1) printf("%I64d\n",ans); else printf("Poor Inna and pony!\n"); } return 0; }