wustoj2244数学

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

扫描二维码关注公众号,回复: 4483811 查看本文章

        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);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/codetypeman/article/details/82185523