函数的魔法 (弗洛伊德查最短路)

链接:https://ac.nowcoder.com/acm/contest/326/C
来源:牛客网
 

题目描述

一位客人来到了此花亭,给了女服务员柚一个数学问题:我们有两个函数,F(X)函数可以让X变成(X*X*X+X*X)mod 233。G(X)函数可以让X变成(X*X*X-X*X)mod 233,我们可以任意的对A使用F(X),和G(X),问最少需要多少次使用这两个函数让A变成B。

输入描述:

第一行输入一个T,表示T组案例(T<100000),然后输入两个整数A,B,表示我们需要把A变成B。(0<=A<=2000000000,0<=B<=2000000000)

输出描述:

输出一个整数表示从A到B最少需要多少次操作,如果不能请输出-1.

思路:这道题和弗洛伊德也能联系起来。。。强,弗洛伊德练的不多,拿此题练手。不过思路挺妙的,我bfs没搞出来,生气

#include <bits/stdc++.h>
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lbt(x) (x&(-x))
#define INF 0x3f3f3f3f
#define IOS ios::sync_with_stdio(false)
#define ll long long
using namespace std;
int a,b,w[240][240];
int f(int x) {
    x%=233;
    return (x*x*x+x*x)%233;
}

int g(int x) {
    x%=233;
    return (x*x*x-x*x)%233;
}

int main() {
    IOS;
    int t;
    cin>>t;
    mem(w,0x3f);
    for(int i=0; i<240; i++) {
        a=f(i),b=g(i);
        w[i][a]=1;
        w[i][b]=1;
    }
    for(int k=0; k<240; k++)
        for(int i=0; i<240; i++)
            for(int j=0; j<240; j++)
                w[i][j]=min(w[i][j],w[i][k]+w[k][j]);
    while(t--) {
        cin>>a>>b;
        if(a == b) {
            printf("0\n");
            continue;
        }
        if(b > 233) {
            printf("-1\n");
            continue;
        } else {
            int x=f(a),y=g(a);
            if(x==b||y==b)
                printf("1\n");
            else {
                if(w[x][b]==INF&&w[y][b]==INF)
                    printf("-1\n");
                else
                    printf("%d\n",min(w[x][b]+1,w[y][b]+1));
            }
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值