题意:你可以进行二种操作:

操作一:
可以将x变成F(x),F(x)=(x * x * x+x * x)%233;
操作二:
可以将x变成G(x),G(x)=(x * x * x-x * x)%233;

求最少多少次可以使a变成b,如果无解则输出-1;

思路:
先对233以内的数到233以内的数进行预处理:
d[i][j]表示i变成j的最少操作次数。
初始化dp[i][j]=一个极大值
dp[i][i]=0;
如果i可以通过一次操作变成j,则dp[i][j]=1;
使用Floyd算法求出i到j的最少操作次数。

预处理后,我们分以下三种情况判断:
①:a==b,输出0;
②:b>=233,输出-1;
③:a先操作一次,然后用预处理的结果求出值。

代码:

#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>

using namespace std;

typedef long long ll;

int d[250][250], inf=233;

int main()
{
    fill(d[0],d[0]+250*250,1000000007);
    for(int i=0; i<233; i++)
    {
        d[i][i]=0;
        for(int j=0; j<233; j++)
        {
            if(i==j)
            {
                continue;
            }
            if((i*i*i+i*i)%233==j)
            {
                d[i][j]=1;
            }
            if((i*i*i-i*i)%233==j)
            {
                d[i][j]=1;
            }
        }
    }
    for(int k=0; k<233; k++)
    {
        for(int i=0; i<233; i++)
        {
            for(int j=0; j<233; j++)
            {
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
            }
        }
    }
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll a, b;
        scanf("%lld%lld",&a,&b);
        if(a==b)
        {
            printf("0\n");
        }
        else if(b>=233)
        {
            printf("-1\n");
        }
        else
        {
            ll z=0;
            int k=(a%inf*a%inf*a%inf+a%inf*a%inf)%inf;
            z=1+d[k][b];
            k=(a%inf*a%inf*a%inf-a%inf*a%inf+inf)%inf;
            z=min(z,(ll)1+d[k][b]);
            if(z>=1000000007)
            {
                z=-1;
            }
            printf("%lld\n",z);
        }
    }
    return 0;
}