您的位置:首页 > 其它

蓝桥杯: 算法训练 2的次幂表示

2017-03-22 21:07 316 查看
问题描述

  任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001。

  将这种2进制表示写成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)

输入格式

  正整数(1<=n<=20000)

输出格式

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

样例输入

137

样例输出

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

样例输入

1315

样例输出

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

提示

  用递归实现会比较简单,可以一边递归一边输出

思路:

用递归实现,一边递归一边输出。

通过观察,发现:137可表示为:2(7)+2(3)+2(0) ,也就是2(2(2)+2+2(0))+2(2+2(0))+2(0)。



很明显,体现了递归思想。

我们只需先获得一个a数组,里面保存【7 3 0】.然后,在一个for循环里,循环3次,每一次取出a中一个元素(7,3,0).然后递归即可(我们只需在递归之前,实现输出 “2(”,然后在递归完之后,输出“)”和“+”,当然“+”在最后一次时不用输出)。

#include<stdio.h>

void A(int n);//递归函数
void ten2two(int n,int* a); // 将10进制转化为2进制,并将非零项的幂保持在数组a中。比如7,二进制位111.那么在数组a中保存a[]={3,2,1,0}(7=2^2+2^1+2^0 ,且a[0]表示数组长度为3).137=2^7+2^3+2^0 那么数组a[]={3,7,3,0}.
int main()
{
int n=0;
scanf("%d",&n);

A(n);
return 0;
}

void A(int n)
{
int a[80]={0};
int i=0;
ten2two(n,a);//若输入n=137,那么得到的a数组值为{3,7,3,0}

for(i=1;i<=a[0];i++)
{
//a[i]==1,即是2^1。此时只用输出2,而不是2(2(0)),所以特别处理。
if(a[i]==1)
{
printf("2");
if(i<a[0])  //如果此时的2^1后面还有2^0,那么要输出"+",并继续for循环
{
printf("+");
continue;
}
else//如果此时的2^1后面没有任何东西,那么不用输出"+",并跳出for循环
{
break;
}
}
//此时a[i]!=1。那么先输出“2(”,在递归A(7),在输出")+"。即是2(递归A(a[i])+)。在最后一次循环中,不输出"+"
printf("2");
printf("(");
A(a[i]);//若是2^0,情况,此处不输出任何东西
//那么就由下面的代码讨论2^0的情况
if(i==a[0] && a[i]==0)
{
printf("0)");
break;
}
printf(")");
//在最后一次循环中,不输出"+"
if(i<a[0])
{
printf("+");
}

}

return;
}

void ten2two(int n,int* a)
{
int i=1,j=1;
int shang=n;
int yu=0;
int b[81]={0};//b存储的十进制数的二进制形式。如137=10001001,那么b[]={8,1,0,0,1,0,0,0,1}。b[0]放的是二进制个数 .那么下面得到的a数组值为{3,7,3,0}
while(shang!=0)
{
yu=shang%2;
shang=shang/2;
b[i]=yu;
i++;
}
i=i-1;
b[0]=i;

for(;i>=1;i--)
{
if(b[i]!=0)
{
a[j]=i-1;
j++;
}
}
a[0]=j-1;
return;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息