题意:
将(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;
}