原题链接

题目描述

约翰的奶牛希望能够非常快速地计算一个数字的整数幂P(1 <= P <= 20,000)是多少,这需要你的帮助。

在它们计算得到最终结果的过程中只能保留两个工作变量用于中间结果。

第一个工作变量初始化为x,第二个工作变量初始化为1。

奶牛可以将任意一对工作变量相乘或相除(可以是一个工作变量与自己相乘或相除),并将结果储存在任意一个工作变量中,但是所有结果都只能储存为整数。

举个例子,如果它们想要得到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的31次方经过六个操作就可得到。

现在给出你希望求得的具体次幂数,请你计算至少需要多少个操作才能得到。

输入格式

输入包含一个整数P,表示具体次幂数。

输出格式

输出包含一个整数,表示所需最少操作数。

数据范围

1≤P≤20000

样例

输入样例:
31
输出样例:
6

算法1 迭代加深IDA*

剪枝:

1.首先容易考虑到:负数和零是不够优秀的。减去负数等效于加上正数,加上负数等效于减去正数,这样可以避免讨论多余的状态;而除了初始状态外,出现零是没有用的:因为这样相当于只有一个数可供操作。这样一定不会比这个非零的数与另一个非零的数合起来更优。

因此,除法操作时,总是用次数的多的除以次数少的,不使用自己除以自己的操作。乘法操作后,不保留0。

2.在当前深度限制下,如果剩下的步骤全部都把较大的数扩大为两倍还是比目标状态小,显然剪枝。

3.对于当前存储器中次数(a,b),设gcd(a,b)=d,那么不管之后怎么操作,得到的次数一定会是d的倍数。因此,如果不满足d|P,那么剪掉。

参考文献

https://blog.csdn.net/rgnoH/article/details/78469464

C++ 代码

#include <cstdio>
#include <iostream>
using namespace std;
int p,depth=0; int gcd( int a,int b )
{
if ( !b ) return a;
return gcd( b,a%b );
} bool IDAstar( int sum,int x,int y )
{
if ( sum==depth )
{
if ( x==p ) return 1;
else return 0;
}
if ( x<<(depth-sum)<p ) return 0;
if ( p%(gcd(x,y))!=0 ) return 0; int a,b; a=x+y; b=y;
if ( b && IDAstar( sum+1,a,b ) ) return 1;
a=x+y; b=x;
if ( b && IDAstar( sum+1,a,b ) ) return 1;
a=x+x; b=y;
if ( b && IDAstar( sum+1,a,b ) ) return 1;
a=x+x; b=x;
if ( b && IDAstar( sum+1,a,b ) ) return 1;
a=y+y; b=x; if ( a<b ) swap( a,b );
if ( b && IDAstar( sum+1,a,b ) ) return 1;
a=y+y; b=y;
if ( b && IDAstar( sum+1,a,b ) ) return 1;
a=x-y; b=x; if ( a<b ) swap( a,b );
if ( b && IDAstar( sum+1,a,b ) ) return 1;
a=x-y; b=y; if ( a<b ) swap( a,b );
if ( b && IDAstar( sum+1,a,b ) ) return 1; return 0;
} int main()
{
scanf( "%d",&p ); while ( !IDAstar( 0,1,0 ) ) depth++; printf( "%d",depth );
}

【题解】AcWing 193. 算乘方的牛的更多相关文章

  1. [题解]Magic Line-计算几何(2019牛客多校第三场H题)

    题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意: 给你偶数个点的坐标,找出一条直线将这n个点分成数量相等的两部分 并在这条直线上取不同的两个点,表示 ...

  2. AcWing 244. 谜一样的牛 (树状数组+二分)打卡

    题目:https://www.acwing.com/problem/content/245/ 题意:有n只牛,现在他们按一种顺序排好,现在知道每只牛前面有几只牛比自己低,牛的身高是1-n,现在求每只牛 ...

  3. AcWing 244. 谜一样的牛|树状数组

    传送门 题目描述 有n头奶牛,已知它们的身高为 1~n 且各不相同,但不知道每头奶牛的具体身高. 现在这n头奶牛站成一列,已知第i头牛前面有Ai头牛比它低,求每头奶牛的身高. 输入格式 第1行:输入整 ...

  4. 题解【[HAOI2006]受欢迎的牛】

    切水题,写题解~ tarjan缩一波点,然后 只有一个出度为0的点:他的size就是答案 有多个初度为0的点:无解,0个 因为是强联通分量,所以肯定有出度为0的点,否则--就是你tarjan写挂了~ ...

  5. AcWing 244. 谜一样的牛

    有n头奶牛,已知它们的身高为 1~n 且各不相同,但不知道每头奶牛的具体身高. 现在这n头奶牛站成一列,已知第i头牛前面有a头牛比它低,求每头奶牛的身高. #include<bits/stdc+ ...

  6. [AcWing 777] 字符串乘方

    点击查看代码 #include<iostream> using namespace std; string str; int main() { while (cin >> st ...

  7. 线性基算贡献——19牛客多校第一场H

    /* 给定数组a[],求有多少集合的异或值为0,将这些集合的大小之和求出来 对于每个数来说,如果除去这个数后数组里做出的线性基和这个数线性相关,那么这个数贡献就是2^(n-1-线性基的大小) 反之这个 ...

  8. AcWing 125. 耍杂技的牛

    //按照wi+si从小到大的顺序排,结果一定最优,最大的危险系数一定是最小的 //类比于国王游戏 #include <iostream> #include <algorithm> ...

  9. 题解【[BJOI2012]算不出的等式】

    题目背景emmm \[\text{首先特判掉p=q时的情况(ans = }p^2-1\text{)}\] \[\text{构造函数}f(k) = \left\lfloor \frac{kq}{p}\r ...

随机推荐

  1. c++ 11字符串与string转换常用函数

    这里主要介绍一下string to int 其他方法与这个类似,可到头文件 <string> 中查看 @_Str 转换的字符串 @_Idx 转换的长度(位数) @_Base 进制 doub ...

  2. UNP——第三章,套接字编程介绍

    1.套接字结构 多数套接字函数都有套接字结构参数,每个协议族都定义了自己的套接字结构,以 sockaddr_ 开始,并对应协议族的唯一后缀. struct sockaddr_in { uint8_t ...

  3. js,昨天的日期

    var mydate = new Date(); var yester = mydate-24*60*60*1000; var yesterday = new Date(); yesterday.se ...

  4. kali 系列学习10-渗透攻击MySQL数据库服务、PostgreSQL数据库服务、Tomcat服务和PDF文件

    介绍使用MSFCONSOLE工具渗透攻击MySQL数据库服务.PostgreSQL数据库服务.Tomcat服务和PDF文件等. 6.4.1 渗透攻击MySQL数据库服务 MySQL是一个关系型数据库管 ...

  5. scala中的val,var和lazy

    转自:https://yerias.github.io/2020/03/19/scala/3/#3%EF%BC%9Alazy%E4%BF%AE%E9%A5%B0%E7%AC%A6%E5%8F%AF%E ...

  6. Mac磁盘清理工具——CleanMyMac

    许多刚从Windows系统转向Mac系统怀抱的用户,一开始难免不习惯,因为Mac系统没有像Windows一样的C盘.D盘,分盘分区明显.因此这也带来了一些问题,关于Mac的磁盘的清理问题,怎么进行清理 ...

  7. 如何正确地安装MathType 7?

    作为一名资深的公式编辑器用户,在新版本MathType 7上线的第一时间,已经去体验了一把.那么要如何正确地安装呢?下面就来详细地介绍下它的安装方法. 步骤一 双击下载好的应用程序,就可以开始安装软件 ...

  8. Guitar Pro吉他指弹入门——双手泛音

    曾经有一段时间在琴行里经常遇到有人来试琴,很多人试弹得曲子就是郑成河的<Flaming>,直译过来就是热情的意思.这首曲子里面有很多泛音存在,吉他泛音类似于钟鸣或者摇铃的声音,是一种令人耳 ...

  9. C语言讲义——指针函数和函数指针

    指针函数 返回值是指针的函数,如void* malloc(...) #include<stdio.h> #include<stdlib.h> #include<strin ...

  10. C语言讲义——传值、传引用

    传值 值类型在做参数的时候,函数内使用的是实参的副本. 函数执行完毕后,即使函数内对参数做了修改,调用方的参数还是原来的值. #include <stdio.h> // 值调用 void ...