LX同学想要游遍整个中国甚至全世界!所以这个国庆假期她计划去长沙玩。但是在她做旅行前的准备的时候,她收到了老师的作业,并且要求在国庆假期结束之前上交!LX同学非常的生气,告诉了你这个消息。你也觉得实在是太过分了,但是没有办法,只好帮助LX同学完成她的作业。
老师给了LX同学两个整数,分别是 x 和 y 。每次LX同学可以从中选择一个数 num ,把这个数变成 (num+2) mod p 或 (num∗2) mod p 或 (num∗num) mod p ,请问,最少需要多少次操作,能使这两个整数相等。
输入格式:
一行三个正整数 x,y,p(3≤p≤106,1≤x,y<p) ,保证p 是一个奇数。
输出格式:
一行一个整数表示最少操作次数。
样例1
输入样例
3 4 5
输出样例
1
样例2
输入样例
2 3 5
输出样例
2
提示
样例一解释:3∗3≡4(mod5) 。
样例二解释:3∗2≡1(mod5) ,1∗2≡2(mod5) 。
这道题我用暴力bfs的做法只能过一部分的测试点,可能是哪里能有化吧,毕竟光是检测是否在队列中都需要进行set里的count方法,数据量又略大,可能还有啥更方便的标记已入队的方法吧.
25分的题只得了13分
//
// Created by TIGA_HUANG on 2020/10/6.
//
#include <iostream>
#include <climits>
#include <set>
#include <queue>
using namespace std;
int p, depth;
struct node {
int x;
int y;
int layer;
};
bool operator<(const node &x, const node &y) {
if (x.x < y.x) return true;
return x.x == y.x && x.y < y.y;
}
int ans = INT_MAX;
set<node> inq;
void bfs(int x, int y) {
queue<node> q;
q.push({x, y});
inq.insert({x, y});
while (!q.empty()) {
node t = q.front();
int layer = t.layer;
if (t.x == t.y) {
cout << t.layer;
return;
}
x = t.x % p;
y = t.y % p;
q.pop();
t.x = (x % p + 2 % p) % p;
t.y = y;
t.layer = layer + 1;
if (!inq.count(t)) {
q.push(t);
inq.insert(t);
}
t.x = (x % p + x % p) % p, t.y = y;
if (!inq.count(t)) {
q.push(t);
inq.insert(t);
}
t.x = (x % p * x % p) % p, t.y = y;
if (!inq.count(t)) {
q.push(t);
inq.insert(t);
}
t.x = x, t.y = (y % p + 2 % p) % p;
if (!inq.count(t)) {
q.push(t);
inq.insert(t);
}
t.x = x, t.y = (y % p + y % p) % p;
if (!inq.count(t)) {
q.push(t);
inq.insert(t);
}
t.x = x, t.y = (y % p * y % p) % p;
if (!inq.count(t)) {
q.push(t);
inq.insert(t);
}
}
}
int main() {
int x, y;
cin >> x >> y >> p;
bfs(x % p, y % p);
return 0;
}