wustoj2244数学

这是一道关于计算从点A到点B通过两种传送方法进行最少次数传送的问题。题目描述了两种传送方式的变换规则,并指出这些变换在某些点上会形成环。解决方法是预处理环上的点,以便在O(1)时间内得到答案。当无法找到从A到B的传送路径时,输出-1。
摘要由CSDN通过智能技术生成

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值