函式的魔法 (弗洛伊德查最短路)
阿新 • • 發佈:2018-12-31
連結: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; }