约翰的奶牛希望能够非常快速地计算一个数字的整数幂 P是多少,这需要你的帮助。
在它们计算得到最终结果的过程中只能保留两个工作变量用于中间结果。
第一个工作变量初始化为 x,第二个工作变量初始化为 11。
奶牛可以将任意一对工作变量相乘或相除(可以是一个工作变量与自己相乘或相除),并将结果储存在任意一个工作变量中,但是所有结果都只能储存为整数。
举个例子,如果它们想要得到 x的 31 次方,则得到这一结果的一种执行方法如下所示:
工作变量1 工作变量2
开始 : x 1
工作变量1与本身相乘,结果置于工作变量2: x x^2
工作变量2与本身相乘,结果置于工作变量2: x x^4
工作变量2与本身相乘,结果置于工作变量2: x x^8
工作变量2与本身相乘,结果置于工作变量2: x x^16
工作变量2与本身相乘,结果置于工作变量2: x x^32
工作变量2除以工作变量1,结果置于工作变量2: x x^31
因此,x的 3131 次方经过六个操作就可得到。
现在给出你希望求得的具体次幂数,请你计算至少需要多少个操作才能得到。
输入格式
输入包含一个整数 P,表示具体次幂数。
输出格式
输出包含一个整数,表示所需最少操作数。
数据范围
1≤P≤200001≤P≤20000
输入样例:
31
输出样例:
6
解题思路:
暴力搜索会超时。我们考虑如何剪枝:
(1.)(1.) 我们可以使用迭代加深搜索 (IDDFS),枚举搜索的深度,一旦合法就输出答案。
(2.)(2.) 我们可以使用可行性剪枝:如果到达一个状态,后面所有的状态都让它翻倍都比最终要求小,则直接返回 false。
(3.)(3.) 对于当前存储器中次数 (a,b) ,设 gcd(a,b)=d,那么不管之后怎么操作,得到的次数一定会是 dd 的倍数。因此,如果不满足 d∣P ,那么剪掉。连续的加加减减很容易让我们想到 gcd。
直接进行搜索即可。可以过题。
(a,b)对于每次的变换,只有以下几种:
1.(a+a,b)
2.(a+a,a)
3.(b+b,a)
4.(b+b,b)
5.(a+b,a)
6.(a+b,b)
7.(a−b,a)
8.(a−b,b)
好了,代码不多说,直接上废话:
#include<bits/stdc++.h>
#define solve if(a<b) swap(a,b); if(b&&dfs(u+1,a,b)) return true
using namespace std;
int gcd(int a,int b)
{
if(b==0)return a;
return gcd(b,a%b);
}
int P,depth;
bool res;
bool dfs(int u,int x,int y)
{
if(res)return true;
if(u==depth)
{
if(x==P)res=true;
return res;
}
if((x<<(depth-u))<P) return false;
if(P%gcd(x,y)!=0)return false;
int a,b;
a=x+y,b=y;solve;
a=x+y,b=x;solve;
a=x+x,b=y;solve;
a=x+x,b=x;solve;
a=y+y,b=x;solve;
a=y+y,b=y;solve;
a=x-y,b=x;solve;
a=x-y,b=y;solve;
return false;
}
int main()
{
cin>>P;
while(!dfs(0,1,0)) depth++;
cout<<depth<<endl;
return 0;
}
以上就是全部了,有其他的问题可以在评论去评论哦诶嘿!
——————今天我花三块买了只蟹哥(螃蟹) 好可爱!!!希望我每天都能像他这样无忧无虑
六年级的唐桑下周见诶嘿!
标签:变量,置于,结果,31,工作,相乘,乘方 From: https://blog.csdn.net/2301_76551733/article/details/136660533