华师一附中OI组
标题:
P1010 幂次方
[打印本页]
作者:
admin
时间:
2018-5-3 11:28
标题:
P1010 幂次方
https://www.luogu.org/problemnew/show/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)
作者:
admin
时间:
2018-5-3 13:46
沙发
#include<iostream>
using namespace std;
void ms(int x)
{
///求出x=2^m+n的m和n
int m=0,n=0,s=1;
while (x>=s){s=s*2;m++;} ///越过后再回头是一种做法
m--;s=s/2;
n=x-s;
///分情况递归
if (m==0) cout<<"2(0)";
else if (m==1) cout<<"2";
else
{
cout<<"2(";
ms(m); ///递归
cout<<")";
}
if (n>0)
{
cout<<'+'; ///分解剩下的那个小尾巴
ms(n);
}
}
int main()
{
for (int x=1; x<=20; x++)
{
ms(x);
cout<<endl;
}
return 0;
}
复制代码
作者:
admin
时间:
2018-5-5 19:39
做题过程:
经过分析,每个数字x都可以分解成2^m+n的唯一形式,因为要求m最大。然后递归就是
主程序
void ms(int x)
{
分解出m和n
再递归 m=0,1 无法递归。
n=0不需要递归
}
写出这一段的框架备用
作者:
admin
时间:
2018-5-5 19:42
怎么求出m呢?仿照s=1+2+4+7+***的那个题,就是求出2^m<=x的最大m
一种常规做法。不断的乘,直到大于,然后减1。
while (x>=s){s=s*2;m++;} ///越过后再回头是一种做法
m--;s=s/2;
n就是x-2^m
这段代码填入
作者:
admin
时间:
2018-5-5 19:43
拼凑出程序,还要自己检查,这个很好办,自己运行x=1--100,手动检查若无问题,即做法正确。
作者:
admin
时间:
2018-5-5 19:47
当然,有创新者,发现N<=20000,意思就是不会超过2^15,于是打个1-2^15的表,然后查表的结果,这也是做法之一,就不吐代码了。
#include <iostream>
using namespace std;
string s[16];
int i,x,a[16];
int main()
{
///这也太搞笑了吧!!!
s[0]="2(0)"; ///1
s[1]="2"; ///2
s[2]="2(2)"; ///4
s[3]="2(2+2(0))"; ///8
s[4]="2(2(2))";
s[5]="2(2(2)+2(0))";
s[6]="2(2(2)+2)";
s[7]="2(2(2)+2+2(0))";
s[8]="2(2(2+2(0)))";
s[9]="2(2(2+2(0))+2(0))";
s[10]="2(2(2+2(0))+2)";
s[11]="2(2(2+2(0))+2+2(0))";
s[12]="2(2(2+2(0))+2(2))";
s[13]="2(2(2+2(0))+2(2)+2(0))";
s[14]="2(2(2+2(0))+2(2)+2)";
cin>>x;
i=0;
while (x>0)
{
a[i]=x%2;
x=x/2;
i++;
}
i=15;
while (a[i]==0) i--;
cout<<s[i];
i--;
for (; i>=0; i--)
if (a[i]==1) cout<<'+'<<s[i];
return 0;
}
复制代码
作者:
倚窗倾听风吹雨
时间:
2018-7-4 20:09
#include<iostream>
using namespace std;
int i,n,s,a[20001]={},j=0;
int cf(int a,int b)
{
int c=2;
for(int x=2;x<=b;x++)c*=2;
if(b==0)c=1;
return c;
}
void kj(int e)
{
int k=1,y;
if(e==0)return;
i=0;
j++;
do i++;
while(cf(2,i)<=e);
y=--i;
a[j]=y;
if(a[j]==0)cout<<"2(0)";
if(a[j]==1)cout<<"2";
if(a[j]>1)
{
cout<<"2(";
kj(a[j]);
cout<<")";
}
if(e!=cf(2,y))
{
cout<<"+";
kj(e-cf(2,y));
}
}
int main()
{
cin>>n;
kj(n);
}
复制代码
作者:
universehyf
时间:
2018-11-24 17:53
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define FOR(i,a,b) for(register int i=a;i<=b;++i)
#define For(i,a,b) for(register int i=a;i>=b;--i)
void dg(int x)
{
if(x==0) {cout<<0;return;}
if(x==2) {cout<<2;return;}
int logg=floor(log(x)*1.00/log(2.00));
///cout<<endl<<x<<" "<<logg<<endl;
bool flag=0;
For(i,logg,0) if((1<<i)&x)
{
if(flag) cout<<"+";flag=1;
if(i==1)cout<<"2";
else{cout<<"2(";dg(i);cout<<")";}
}
}
int main()
{
int n;scanf("%d",&n);
dg(n);return 0;
}
复制代码
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2