1. 程式人生 > >牛客練習賽35 C.函數的魔法

牛客練習賽35 C.函數的魔法

mod inf || http mem %d 一行 如果 ++

鏈接

[https://ac.nowcoder.com/acm/contest/32]

題意

題目描述
一位客人來到了此花亭,給了女服務員柚一個數學問題:我們有兩個函數,F(X)函數可以讓X變成(XXX+XX)mod 233。G(X)函數可以讓X變成(XXX-XX)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.
示例1
輸入
復制
1
2 186
輸出
復制
2
說明
我們首先使用F(X),將2變成(22

2+22)mod 233=12。然後我們再將12通過G(X),變成(121212-1212)mod 233=186

分析

floyd的應用,看代碼就知道了

代碼

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=233;
int dp[310][310];
int t,a,b,cnt,n;
int f(int x){
    x%=mod; return (x*x*x+x*x)%mod;
}
int g(int x){
    x%=mod; return (x*x*x-x*x)%mod;
}
void init()
{
    memset(dp,inf,sizeof(dp));
    for(int i=0; i<mod; i++)
    {
        dp[i][f(i)]=1;
        dp[i][g(i)]=1;
        dp[i][i]=0;
    }
    for(int k=0; k<mod; k++)
        for(int i=0; i<mod; i++)
            for(int j=0; j<mod; j++)
                if(dp[i][k]!=inf&&dp[k][j]!=inf)
                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
}
int main(){
     
    scanf("%d",&t);
    init();
//  for(int i=0; i<mod; i++){
//      for(int j=0; j<mod; j++)
//      cout<<dp[i][j]<<‘ ‘;
//      cout<<endl;
//  }
// 
    while(t--){
        scanf("%d%d",&a,&b);
        if(a==b) printf("0\n");
        else if(b>=mod) printf("-1\n");
        else{
            if(a>=mod){
            //  cout<<1<<endl;
                cnt=1;
                n=f(a);
                a=g(a);
                if(dp[a][b]<inf||dp[n][b]<inf){
                    cnt+=min(dp[a][b],dp[n][b]);
                    printf("%d\n",cnt);
                }
                else printf("-1\n");
            }
            else{
                //cout<<2<<endl;
                if(dp[a][b]!=inf) printf("%d\n",dp[a][b]);
                else printf("-1\n");
            }
        }
    }
    return 0;
}

牛客練習賽35 C.函數的魔法