1000ms
65536kB
任何一个正整数都可以用2的幂次方表示。例如:
137=2^7+2^3+2^0
同时约定方次用括号来表示,即ab可表示为a(b)。由此可知,137可表示为:
2(7)+2(3)+2(0)
进一步:7=2^2+2+2^0(21用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)
【数据范围】
对于 100% 的数据,1≤n≤2×10^4。
这个算法很多人都会写了,思路如下:
至此,思路就很清晰了,那么我就上代码吧(很多人都会了不详解了)
//认真看,杜绝抄袭
#include
using namespace std;
int n;
void search(int x)
{if(n!=0){int p=1,q=0;printf("2");//每一次搜索都要输出2 //如果是1次幂就没必要写2(1),后面会说; while(x>=p){++q; p*=2; }//计算幂,由于这里会多算一次,所以计数器q-1; --q;if(q==0 || q==2)printf("(%d)",q);//各种括号的判断if(q>=3){printf("("); search(q);printf(")");}x-=p/2;//上面计数器就是多算了一次,因此p也多乘了一个2; if(x)//输入的数x为真(最后分解完就成0了,变成假),输出"+"; {printf("+");search(x);}}
}
int main()
{scanf("%d",&n);search(n);return 0;//别忘了写;
}
下面讲一种高级的:
我们知道,二进制数表示的其实就是一个正整数分解成为2的幂次方和!
如3用二进制表示为 11 ,从右到左分别是第0位,第1位……
则3=2^1+2^0(只要二进制那位是一,就是2^(这一位))
再比如10 二进制是1010,则10=2^3+2^1;
大家自己体会一下
下面更高级的:位运算(其实也不高级,就是没人做)
不会位运算的就用上面那种吧,个人觉得位运算更快(普通14ms,位运算11ms)
位运算具体问度娘吧
思路如下:
二进制代码实现如下:
//认真看,杜绝抄袭
#include
using namespace std;
void ASCII(int m)
{int i=0,k=m,u=0,h[50];while(k)//位运算实现;{if(k&1)h[++u]=i;//h[++u]相当于++u,h[u]…… k>>=1;i++;}//据上面写的,u从1开始,无论如何一定会有输出; while(u)//u为真 {if(h[u]<3)//具体括号判断;{if(h[u]==1 && u-1!=0) printf("2+");else if(h[u]==1) printf("2");if((h[u]==0||h[u]==2)&&(u-1!=0)) printf("2(%d)+",h[u]);else if(h[u]==0||h[u]==2) printf("2(%d)",h[u]); --u;//搜索下一个;}else{printf("2(");ASCII(h[u--]);//相当于h[u],--u; //这里千万不能写成 h[--u],否则你会3个WA两个MLE; if(u!=0)printf(")+");//由于u进行了自减,此时的u已经是下一个数了; else printf(")");//判断括号;} }
}
int main()
{int n;scanf("%d",&n);ASCII(n);return 0;//别忘了写;
}
这道题并不怎么难,只需要基本的算法就可以解决,难点是输出括号和加号的时候容易出错 。
https://www.luogu.com.cn/problem/P1010https://www.luogu.com.cn/problem/P1010
下一篇:前端资源浏览器渲染原理