luogu P1010 幂次方

题目描述

任何一个正整数都可以用2的幂次方表示。例如

    137=2^7+2^3+2^0         

同时约定方次用括号来表示,即a^b 可表示为a(b)。

由此可知,137可表示为:

    2(7)+2(3)+2(0)

进一步:7= 2^2+2+2^0 (2^1用2表示)

    3=2+2^0   

所以最后137可表示为:

    2(2(2)+2+2(0))+2(2+2(0))+2(0)

又如:

    1315=2^10 +2^8 +2^5 +2+1

所以1315最后可表示为:

    2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

输入输出格式

输入格式:

一个正整数n(n≤20000)。

 

输出格式:

符合约定的n的0,2表示(在表示中不能有空格)

 

输入输出样例

输入样例#1:
1315
输出样例#1:
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

看到这个题正解明显的递归
解法一之递归:
用一个递归为mi,找到n-2^i最小,判断:
  i==0: printf("2(0)");
  i==1: printf("2");
  i==2: printf("2(2)");
  如果i>2,则调用递归:mi(i)
  上面做完后,判断n-2^i是否为0,不为0则调用递归:mi(n-2^i)。
代码来咯:
#include <cstdio>
#include <cstdlib>
#include <stdio.h>
using namespace std;

long n;

int mi(int m){
    int i=0,t=1;
    while (t*2<=m){
        t=t*2;
        i=i+1;
    }
    if (i==0) printf("2(0)");
    if (i==1) printf("2");
    if (i==2) printf("2(2)");
    if (i>2) {
        printf("2("); mi(i); printf(")");
    }
    if (m-t>0) {
        printf("+");
        mi(m-t);
    }
}

int main(){
    scanf("%d",&n);
    mi(n);
    return 0;
}

解法二打表枚举:

n既然<=20000,2的16次方貌似就超了吧,所以可以吧这些数每一位一位的拆开,打个16个情况的表,照例输出就好了。
(打表虽然比较low但总比递归调不出来,木有分好吧)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
    int n,m,k=0,a[100000];
    cin>>n;
    while(n>0)
    {
        for(int i=0; i<=15; i++)
        {
            m=pow(2,i);
            if(m>=n)
            {
                if(m==n)
                {
                    n=n-m;
                    k++;
                    a[k]=i;
                }
                if(m>n)
                {
                    n=n-pow(2,i-1);
                    k++;
                    a[k]=i-1;
                }
                break;
            }
        }
    }
    if(a[1]==0)cout<<"2(0)";
    if(a[1]==2)cout<<"2(2)";
    if(a[1]==3)cout<<"2(2+2(0))";
    if(a[1]==4)cout<<"2(2(2))";
    if(a[1]==5)cout<<"2(2(2)+2(0))";
    if(a[1]==6)cout<<"2(2(2)+2)";
    if(a[1]==7)cout<<"2(2(2)+2+2(0))";
    if(a[1]==8)cout<<"2(2(2+2(0)))";
    if(a[1]==9)cout<<"2(2(2+2(0))+2(0))";
    if(a[1]==10)cout<<"2(2(2+2(0))+2)";
    if(a[1]==11)cout<<"2(2(2+2(0))+2+2(0))";
    if(a[1]==12)cout<<"2(2(2+2(0))+2(2))";
    if(a[1]==13)cout<<"2(2(2+2(0))+2(2)+2(0))";
    if(a[1]==14)cout<<"2(2(2+2(0))+2(2)+2)";
    if(a[1]==1)cout<<"2";
    for(int i=2; i<k; i++)
    {
        if(a[i]==0)cout<<"+2(0)";
        if(a[i]==2)cout<<"+2(2)";
        if(a[i]==3)cout<<"+2(2+2(0))";
        if(a[i]==4)cout<<"+2(2(2))";
        if(a[i]==5)cout<<"+2(2(2)+2(0))";
        if(a[i]==6)cout<<"+2(2(2)+2)";
        if(a[i]==7)cout<<"+2(2(2)+2+2(0))";
        if(a[i]==8)cout<<"+2(2(2+2(0)))";
        if(a[i]==9)cout<<"+2(2(2+2(0))+2(0))";
        if(a[i]==10)cout<<"+2(2(2+2(0))+2)";
        if(a[i]==11)cout<<"+2(2(2+2(0))+2+2(0))";
        if(a[i]==12)cout<<"+2(2(2+2(0))+2(2))";
        if(a[i]==13)cout<<"+2(2(2+2(0))+2(2)+2(0))";
        if(a[i]==14)cout<<"+2(2(2+2(0))+2(2)+2)";
        if(a[i]==1)cout<<"+2";
    }
}
View Code

 
posted @ 2018-04-14 19:38  Manjusaka丶梦寒  阅读(173)  评论(0编辑  收藏  举报