题意:题目给出一个集合{3^0,3^1,3^2,3^3,3^4,3^5,3^6,···,3^n},以其所有子集中各元素之和为基准,从小到大排列该集合的所有子集:
{ },{ 1 },{ 3 },{ 1, 3 },{ 9 },{ 1, 9 },{ 3, 9 },{ 1, 3, 9 },{ 27 },{ 1, 27 },{ 3, 27 },{ 1, 3, 27 },{ 9, 27 },{ 1, 9, 27 },{ 3, 9, 27 },{ 1, 3, 9, 27 }···
其和为别为:0,1,3,4,9,10,12,13,27,28,30,31,36,37,39,40···
为别对应位置:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16···
题目要求输入一个数字a(位置),输出该位置上相应的集合。
经观察,发现:2^n<a<=2^n+1时,待输出位置上的集合中必有元素3^n。沿用这个思路,每输出一个3^n,a减少2^n,减少到a==1为止(1号位置的不用输出)。
题目要求输入的a不超过19位,因为2^65为20位数字,则原集合中最多有64个元素,其中最大元素的是3^63。因为3^63不超过32位,则开一个字符型数组data[65][32],data[0]中存"\0",data[1]至data[64]中存3^0至3^63。
字符数组data[65][32],采用本地指标方式进行了初始化(为了省时省空间)。
下面是制表代码:
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
const int size=1000; //大数位数
void mult(char* A,char* B,char* ans)
{
int a[size+1]={0};
int b[size+1]={0};
int pa=0,pb=0;
int c[2*size+1]={0};
int lena=strlen(A);
int lenb=strlen(B);
for(int i=lena-1;i>=0;i--)
a[pa++]=A[i]-'0';
for(int j=lenb-1;j>=0;j--)
b[pb++]=B[j]-'0';
for(pb=0;pb<lenb;pb++)
{
int w=0; //低位到高位的进位
for(pa=0;pa<=lena;pa++)
{
int temp=a[pa]*b[pb]+w;
w=temp/10;
temp=(c[pa+pb]+=temp%10);
c[pa+pb]=temp%10;
w+=temp/10;
}
}
bool flag=false;
bool sign=false; //标记ans是否为全0
for(pa=0,pb=lena+lenb-1;pb>=0;pb--)
{
if(!flag && c[pb]==0) //删除ans开头的0
continue;
else
flag=true;
sign=true;
ans[pa++]=c[pb]+'0';
}
if(sign)
ans[pa]='\0';
else
{
ans[0]='0';
ans[1]='\0';
}
return;
}
char a[size+1];
char ans[size*size+1];
int main(void)
{
int b;
for(b=0;b<64;b++)
{
a[0]='3';
ans[0]='1';
ans[1]='\0';
for(int i=1;i<=b;i++)
mult(a,ans,ans);
cout<<"""<<ans<<"""<<",";
}
return 0;
}
#include<string>
#include<cstring>
using
const
void
{
}
char
char
int
{
}
将输出粘贴复制进data[65][32]数组中即可(⊙o⊙)…
接着是本体的代码:
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int process(double n) //取出元素3^i-1,即data[i]
{
double i=0,t=1;
while(t<n)
{
t*=2;
i++;
}
return i;
}
int main()
{
int temp,j;
double n;
char result[65][32],data[65][32]={"\0","1","3","9","27","81","243","729","2187","6561",
"19683","59049","177147","531441","1594323","4782969","14348907",
"43046721","129140163","387420489","1162261467","3486784401",
"10460353203","31381059609","94143178827","282429536481","847288609443",
"2541865828329","7625597484987","22876792454961","68630377364883","205891132094649",
"617673396283947","1853020188851841","5559060566555523","16677181699666569",
"50031545098999707","150094635296999121","450283905890997363","1350851717672992089",
"4052555153018976267","12157665459056928801","36472996377170786403","109418989131512359209",
"328256967394537077627","984770902183611232881","2954312706550833698643","8862938119652501095929", "26588814358957503287787","79766443076872509863361","239299329230617529590083 ","717897987691852588770249 ", "215369396307555776631074 7","646108188922667329893224 1","193832456676800198967967 23","581497370030400596903901 69", "174449211009120179071170 507","523347633027360537213511 521","157004289908208161164053 4563","471012869724624483492160 3689", "141303860917387345047648 11067","423911582752162035142944 33201","127173474825648610542883 299603","381520424476945831628649 898809",
#include<cmath>
#include<cstring>
using
int
{
}
int
{
"114456127343083749488594 9696427"};
while(cin>>n&&n!=0)
{
j=0;
while(n>1)
{
temp=process(n);
strcpy(result[j++],data[temp]);
n-=pow(2.0,temp-1);
}
if(j==0)cout<<"{ }"<<endl;
else
{
cout<<"{ ";
while(j>1)
cout<<result[--j]<<", ";
cout<<result[--j]<<" }"<<endl;
}
}
return 0;
}
}