Three powers


Time Limit:1s Memory limit:32M
Accepted Submit:96 Total Submit:217

Consider the set of all non-negative integer powers of 3.

 

S = { 1, 3, 9, 27, 81, ... }

 

Consider the sequence of all subsets of S ordered by the value of the sum of their elements. The question is simple: find the set at the n-th position in the sequence and print it in increasing order of its elements.

Input

Each line of input contains a number n, which is a positive integer with no more than 19 digits. The last line of input contains 0 and it should not be processed.

Output

For each line of input, output a single line displaying the n-th set as described above, in the format used in the sample output.

Sample input

1
7
14
783
1125900981634049
0

Output for sample input

{ }
{ 3, 9 }
{ 1, 9, 27 }
{ 3, 9, 27, 6561, 19683 }
{ 59049, 3486784401, 205891132094649, 717897987691852588770249 }

Original: Waterloo

 

解题:

       题目的意思是,3的次幂所组成的集合S,按从小到大排列组合成一些数,最小的为空,比如:{},{1},{3},{1,3},{9}···刚开始还是没发现规律,查了下资料发现二进制关系。如前几项组合成的数为0,1,3,4,9,10,12····相对应的项数为0,1,2,3,4,5,6··化为二进制0,1,10,11,100,101··于是可以发现二进制上为1的,S集合中相对应的项则有出现,但是项数是从0开始的,所以程序取的n要减去1。题目要求n是最多19位的数,预计3的次幂可能会很大,采用预先生成3的64以下的各次幂。

生成方法如下:(需要调用大数模板

int main() { int i,j; ofstream outfile("D://3的幂运算.txt"); bignum a; a.P(1,0); outfile<<"/""<<a<<"/","<<endl; for(i=1;i<64;i++) { a*=3; outfile<<"/""<<a<<"/","<<endl; } }

 

以下是本题的代码:

#include <iostream> using namespace std; //typedef unsigned __int64 i64; typedef unsigned long long i64; char a[64][50]={ "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", "2153693963075557766310747", "6461081889226673298932241", "19383245667680019896796723", "58149737003040059690390169", "174449211009120179071170507", "523347633027360537213511521", "1570042899082081611640534563", "4710128697246244834921603689", "14130386091738734504764811067", "42391158275216203514294433201", "127173474825648610542883299603", "381520424476945831628649898809", "1144561273430837494885949696427"}; int toTwo(i64 n,int twoBit[]) { int i=0; while (n) { twoBit[i++]=n%2; n/=2; } return i; } int main() { i64 n=0;int i,j,length; int twoBit[100]; while (scanf("%llu",&n)&& n!=0) //while (scanf("%I64u",&n)&& n!=0) { length=toTwo(n-1,twoBit); printf("{"); for(i=0;i<length;i++) { if(twoBit[i]==1) { printf(" %s",a[i]); for(j=i+1;j<length;j++) if (twoBit[j]==1) printf(", %s",a[j]); break; } } printf(" }/n"); } return 0; }