Teleportation
Time Limit: 1 Sec
Description
Hovey just learnt a powerful skill from the failurc of his chasing MMs: teleportation. He can teleport from point (x , y) to another point (x', y') by using one of the two following methods.
T1: ( x' , y' ) <-- ( x-y , 2y-x )
T2: ( x' , y' ) <-- ( 2y-x , 2x-3y )
You should notice that all the numbers are non-negative integers and calculated modulo 1000.
Now you are going to find out the minimum times of teleportation to get from point A to point B. .
Input
There are multiple test cases. The first line contains an integer T, the number of cases.
In each cases, there are four non-negative integers in a single line, (Xa,Ya), (Xb, Yb), indicating the query point A and B. All integers are less than 1000.
Output
For each test case, output one line contairung the minimum times ofteleportation to get from A to B. If there is no solution, output -1 instead.
题意从一个点到另一个点,两种变换方式,求最少需要多次变换;
第一眼一看,这不是个bfs的sb题吗?然后其他队全部tle,后来发现可以倒退,然后写双向t,le,然后自闭了……
题解: T1,T2其实是T( x , y) ——>( y, x-y) 的一个子变化,T1=T*2,T2=T*3;
那么其实只需关注做了多少次T变化即可得到答案;
然后发现,T变化其实在一些点内是成环的,所以只需找出每个环以及上面的点,预处理一下,每次o( 1 )的得到答案;
#include <bits/stdc++.h>
#define bug puts("\nbug")
using namespace std;
const int maxn=1005;
int fuck;
int sx,sy,ex,ey;
int vis[maxn][maxn];
int mark[maxn][maxn];
int sz[maxn*maxn];
void init()
{
memset(vis,-1,sizeof vis);
int tag=1;
for(int i=0;i<1000;++i)
for(int j=0;j<1000;++j)
{
if(vis[i][j]==-1)
{
int x=i;
int y=j;
int st=0;
mark[i][j]=tag;
while(x>=0&&y>=0)
{
vis[x][y]=st;
mark[x][y]=tag;
++st;
int t=x;
x=y;
y=(t-y+1000)%1000;
if(vis[x][y]!=-1) break;
}
sz[tag]=st;
++tag;
}
}
}
int main()
{
cin>>fuck;
init();
while(fuck--)
{
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
if(mark[sx][sy]!=mark[ex][ey])
{
cout<<-1<<endl;
}
else
{
int len=(vis[ex][ey]-vis[sx][sy]+sz[mark[sx][sy]])%sz[mark[sx][sy]];
if(len==1) len=sz[mark[sx][sy]]+1;///只有一次T变化,但至少要两次,所以要把环走完
if(len%3==0) printf("%d\n",len/3);
else printf("%d\n",len/3+1);
}
}
}