算乘方的牛

文章描述了一种计算给定数字的整数幂的最少操作步骤问题,利用迭代加深搜索和可行性剪枝策略,通过工作变量的加减乘除操作来优化计算过程。作者给出了C++代码实现这一算法。
摘要由CSDN通过智能技术生成

约翰的奶牛希望能够非常快速地计算一个数字的整数幂 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;
}

以上就是全部了,有其他的问题可以在评论去评论哦诶嘿!

                                                                                                                                             ——————今天我花三块买了只蟹哥(螃蟹) 好可爱!!!希望我每天都能像他这样无忧无虑

六年级的唐桑下周见诶嘿!

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值