题解 UVA1374 【快速幂计算 Power Calculus】

明显的搜索题

本题我提供两种方法:打表和搜索。

第一种方法:打表

俗话说的好:

暴力出奇迹,骗分过样例。

数学先打表,DP看运气。

全文见我主页

搜索也可以打表!

打表,没什么好说的。

但是数据有1000,怎么打表呢?

这你就不用管了

上代码(具体细节见第二种方法):

#include<bits/stdc++.h>
using namespace std;
int a[1001]={0,0,1,2,2,3,3,4,3,4,4,5,4,5,5,5,4,5,5,6,5,6,6,6,5,6,6,6,6,7,6,6,5,6,6,7,6,7,7,7,6,7,7,7,7,7,7,7,6,7,7,7,7,8,7,8,7,8,8,8,7,8,7,7,6,7,7,8,7,8,8,8,7,8,8,8,8,8,8,8,7,8,8,8,8,8,8,9,8,9,8,9,8,8,8,8,7,8,8,8,8,9,8,9,8,9,9,9,8,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,8,9,8,8,7,8,8,9,8,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,10,9,9,9,9,9,9,9,9,8,9,9,9,9,9,9,10,9,10,9,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,9,10,9,9,9,9,8,9,9,9,9,10,9,10,9,10,10,10,9,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,9,10,9,9,8,9,9,10,9,10,10,10,9,10,10,11,10,11,10,10,9,10,10,11,10,11,10,10,10,10,10,10,10,10,10,10,9,10,10,10,10,10,10,11,10,10,10,11,10,11,11,11,10,11,10,11,10,11,10,11,10,11,10,10,10,10,10,10,9,10,10,10,10,10,10,11,10,11,10,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,10,11,11,11,10,11,10,11,10,10,10,10,9,10,10,10,10,11,10,11,10,11,11,11,10,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,12,11,12,11,11,11,12,11,12,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,12,11,12,11,11,10,11,11,12,11,12,11,11,10,11,11,11,10,11,10,10,9,10,10,11,10,11,11,11,10,11,11,12,11,12,11,11,10,11,11,12,11,12,12,11,11,12,12,12,11,12,11,11,10,11,11,12,11,12,12,12,11,11,12,12,11,12,11,12,11,11,11,12,11,12,11,11,11,12,11,11,11,11,11,11,10,11,11,11,11,11,11,12,11,11,11,12,11,12,12,12,11,12,11,12,11,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,11,12,11,12,11,11,11,11,11,11,10,11,11,11,11,11,11,12,11,12,11,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,11,12,12,12,11,12,11,12,11,11,11,11,10,11,11,11,11,12,11,12,11,12,12,12,11,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,13,12,12,12,12,11,12,12,12,12,13,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,12,12,12,13,12,13,12,12,12,13,12,12,12,12,12,12,11,12,12,12,12,12,12,13,12,12,12,13,12,13,12,12,12,13,12,13,12,13,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,13,13,12,13,13,13,12,13,12,13,12,13,13,13,12,13,13,13,12,13,12,13,12,12,12,13,12,13,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,13,12,13,12,12,12,12,12,13,12,13,13,13,12,13,13,13,12,13,12,12,11,12,12,13,12,13,13,13,12};
int main()
{
    int n;
    while(cin>>n)
    {
        if(n==0)
        {
            break;
        }
        cout<<a[n]<<endl;
    }
    return 0;
}
View Code

优点:速度快。

第二种方法:迭代深搜

这道题要用到迭代深搜。

Question:迭代深搜是什么?

Answer:迭代深搜,即IDDFS,它是按照深度优先搜索的方式遍历,但是,与其不同的是:迭代深搜会枚举搜索深度,它的效率要比普通的DFS快,与广度优先算法速度是等价的。

接下来看看这题,枚举项数,然后搜索。

有两种特殊情况:

当N=1时,输出0。

当N=0时,跳出循环。

用代码实现即:

if(n==0)
{
    break;
}
if(n==1)
{
    printf("0\n");
    continue;
}
View Code

顺便说一句,请勿抄题解!

其他部分没有问题,只不过要剪枝。剪枝也不难,在当前情况不可能成立时,return。代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,dep;
int a[101];
bool dfs(int step,int now)
{
    if(step>dep||now<=0||now*pow(2,dep-step)<n)
    {
        return false;
    }
    if(now==n||now*pow(2,dep-step)==n)
    {
        return true;
    }
    a[step]=now;
    int i;
    for(i=0;i<=step;i++)
    {
        if(dfs(step+1,now+a[i]))
        {
            return true;
        }
        if(dfs(step+1,now-a[i]))
        {
            return true;
        }
    }
    return false;
}
int main()
{
    while(1==scanf("%d",&n))
    {
        if(n==0)
        {
            break;
        }
        if(n==1)
        {
            printf("0\n");
            continue;
        }
        dep=0;
        a[0]=1;
        while(!dfs(0,1))
        {
            dep++;
        }
        printf("%d\n",dep);
    }
    return 0;
}
View Code
posted @ 2020-08-08 15:28  Bushuai_Tang  阅读(145)  评论(0编辑  收藏  举报