(此为洛谷题)
这题目一看,就感觉很麻烦,不仅要给输入的数转化为二进制,而且要把得出来的数也统统转化为二进制,但是数据最大就2*10^4
也就是说,他不超过2^15,只要用1到14就能表示转化过的数(指2的次方中的数)
说明实际上不要多次转换,只要提前把1到14转换成题目所需格式就可以:
//1 2(0)
//2 2
//3 2+2(0)
//4 2(2)
//5 2(2)+2(0)
//6 2(2)+2
//7 2(2)+2+2(0)
//8 2(2+2(0))
//9 2(2+2(0))+2(0)
//10 2(2+2(0))+2
//11 2(2+2(0))+2+2(0)
//12 2(2+2(0))+2(2)
//13 2(2+2(0))+2(2)+2(0)
//14 2(2+2(0))+2(2)+2
然后完成第一步(将输入的数转化为二进制),按需输出就可以了
代码实现:
#include
int main(void)
{
//提前处理
int k[15] = {0};
int n, i;
int num = 0;//用来记1的数量并调节输出“+”
scanf("%d", &n);
//十进制转二进制
for(i = 0; n != 1; i++)
{
if(k[i] = n % 2)
num++;
n /= 2;
}
k[i] = 1;
//输出处理
for(int j = i; j >= 0; j--)
{
switch(j)
{
case 0:
if(k[j])
printf("2(0)");
break;
case 1:
if(k[j])printf("2");
break;
case 2:
if(k[j])
printf("2(2)");
break;
case 3:
if(k[j])
printf("2(2+2(0))");
break;
case 4:
if(k[j])
printf("2(2(2))");
break;
case 5:
if(k[j])
printf("2(2(2)+2(0))");
break;
case 6:
if(k[j])
printf("2(2(2)+2)");
break;
case 7:
if(k[j])
printf("2(2(2)+2+2(0))");
break;
case 8:
if(k[j])
printf("2(2(2+2(0)))");
break;
case 9:
if(k[j])
printf("2(2(2+2(0))+2(0))");
break;
case 10:
if(k[j])
printf("2(2(2+2(0))+2)");
break;
case 11:
if(k[j])
printf("2(2(2+2(0))+2+2(0))");
break;
case 12:
if(k[j])
printf("2(2(2+2(0))+2(2))");
case 13:
if(k[j])
printf("2(2(2+2(0))+2(2)+2(0))");
break;
case 14:
if(k[j])
printf("2(2+2(0))+2(2)+2");
break;
}
if(k[j] && num != 0)
{
printf("+");
num--;
}
}
return 0;
}
//1 2(0)
//2 2
//3 2+2(0)
//4 2(2)
//5 2(2)+2(0)
//6 2(2)+2
//7 2(2)+2+2(0)
//8 2(2+2(0))
//9 2(2+2(0))+2(0)
//10 2(2+2(0))+2
//11 2(2+2(0))+2+2(0)
//12 2(2+2(0))+2(2)
//13 2(2+2(0))+2(2)+2(0)
//14 2(2+2(0))+2(2)+2
实际上应该不断嵌套解的,这也是一种偷鸡的方法(乐)
不过洛谷的测试点5有问题呀
输入是16385
而测试输出是2(2(2+2(0))+2(2)+2)+2(0)
不管怎么说也应该是2(2(2+2(0))+2(2)+2+2(0)呀(就是把那个奇怪的括号去掉)
(补充:后面发现是自己在2^14处的输出有问题。。。偷鸡有风险啊。。。)
以后有机会试一试不偷鸡的方法
补充:
来了来了,第二天就试了一下不偷鸡的方法,发现还挺好写的(我之前累死累活把1~14手动转化为二进制是为了什么)(偷鸡的代价)
附上代码:
#include
void Power_to_the_power(int n);
//主函数
int main(void)
{
int num;
scanf("%d", &num);
Power_to_the_power(num);
return 0;
}
//函数
void Power_to_the_power(int n)
{
int k[15] = {0};
int length = 0;
int i;
//十进制转二进制(因为获得的二进制是逆序的,所以还是需要存储)(输出是顺序的)
for(i = 0; n != 1; i++)
{
if(k[i] = n % 2)
length++;
n /= 2;
}
k[i] = 1;
//开始输出以及递归
for(; i > -1; i--)
{
if(k[i])
{
switch (i)
{
case 0:
printf("2(0)");
break;
case 1:
printf("2");
break;
default:
printf("2(");
Power_to_the_power(i);
printf(")");
break;
}
if(length != 0)
{
printf("+");
length--;
}
}
}
return;
}
但是还是有可以改进的地方,因为我用的是常规的十进制转二进制的方法,所得到的二进制数是从低到高的,只能设置数组存储,以后学一学把十进制顺序转二进制的方法,就可以一边计算一边输出了,不需要存储。
补充:
嗨嗨嗨,我又来了。
上网搜了搜将十进制转化为二进制的方法,发现清一色的整除取余法,没有一个是顺序输出的。后面自己就想到了对数转化法。
就是先用log来转化所需要的数(函数为log()或者log10(),具体上网搜),得到一个数,这个数取整数部分就是该数转化为二进制的最高位。
通过这个思路,就可以完成十进制向二进制的顺序转化了。
代码如下:
#include
#include
void Decimal_to_binary(int );
int main(void)
{
int n;
scanf("%d", &n);
Decimal_to_binary(n);
return 0;
}
void Decimal_to_binary(int n)
{
int num = log(n) / log(2);
while(n)
{
int new_num = log(n) / log(2);
n -= pow(2, new_num);
for(int j = 0; j < (num - new_num - 1); j++)
printf("0");
printf("1");
num = new_num;
}
//考虑最低位为0的情况
while(num--)
printf("0");
return;
}
通过这种方法,我们可以进一步优化题解:
#include
#include
void Decimal_to_binary(int );
int main(void)
{
int n;
scanf("%d", &n);
Decimal_to_binary(n);
return 0;
}
void Decimal_to_binary(int n)
{
while(n)
{
int new_num = log(n) / log(2);
n -= pow(2, new_num);
if(new_num > 1)
{
printf("2(");
Decimal_to_binary(new_num);
printf(")");
}
else if(new_num)
printf("2");
else
printf("2(0)");
//考虑需要用+的情况
if(n)
printf("+");
}
return;
}
代码简洁多了,真不错
补充:还有一个用位运算符来进行十进制转化为二进制的
代码如下:
#include
#include
char * itobs(int,char *);
void show_bstr(const char *);
int main(void)
{
char bin_str[CHAR_BIT * sizeof(int) + 1];
int number;
puts("输入一个数字,我将把他转换为二进制(空一行结束):");
while(scanf("%d",&number)==1)
{
itobs(number,bin_str);
printf("%d 转换为二进制为",number);
show_bstr(bin_str);
putchar('\n');
}
puts("Bye!");
return 0;
}
char * itobs(int n,char * ps)
{
int i;
const static int size = CHAR_BIT * sizeof(int);
for(i=size-1;i>=0;i--,n>>=1)
ps[i]=(01 & n) + '0';
ps[size] = '\0';
return ps;
}
void show_bstr(const char * str)
{
int i = 0;
while(str[i])
{
putchar(str[i]);
if(++i % 4 == 0 && str[i])
putchar(' ');
}
}
(该代码摘自《C Primer Plus》)
这代码是我高中是学到位运算符时抄到U盘里的,现在全都忘光了,放这里权当参考。