Description
这一周,王子开始研究起天平来。王子叫她工匠做了一个很特别的天平。之所以特别是因为这个天平的左右两边都可以放砝码,同时砝码重量都是3的指数倍,即3^0,3^1,……,3^63,每一种砝码各一个(单位为克,本题提到的重量单位都为克)共64个砝码。这一次王子把漂亮的公主叫来一起做天平游戏,游戏是这样的,王子往天平左盘放一物体,公主从64个砝码中选若干个放在左盘或右盘使得天平平衡,作为公主助手的你能帮帮她吗?
Input
一个正整数M,表示王子放在左盘物体的重量。(1=<M<=1015,输入以文件结束)
Output
对于每一组: 如果有解,输出有两行。 第一行为放在左盘的砝码的重量,从大到小输出每个砝码重量,各个数以一个空格隔开。如果左盘不用放,则输出0. 第二行为放在右盘的砝码的重量,从大到小输出每个砝码重量,各个数以一个空格隔开。 如果有多组解,则输出左盘和右盘砝码总重量最小的解。 如果无解,输出一行。 no solution!
Sample Input 3
5
Sample Output 0
3
3 1
9
Source chenjiangyong@fjnu 一开始以为是用母函数,可是数据ms不小的说,于是从三进制入手 1.先从最简单的例子开始说起: 如果所给的数可以表示为3^a1 + 3^a2+ 3^a3...+3^ai(为了方便,设ai是递减的) 那么就可以表示成由且 只由1,0组合而成的3进制的数 如:3->10 9->100 28->1001 ......等,如果给的是这样的数,那很明显左盘不用放什么东西了 ,就可以得到这种情况的答案了; (其实就是最简单的2边质量要相等.可以很容易的想到.~~~) 2.再深思一下,如sample中的5,5的三进制是12. (首先要明确所有的砝码都只有一个,所以不可能出现左边的砝码 的重量的三进制表示和右边的砝码的重量的三进制在某一位都为1 也就是不可能出现例如左边是110 右边是011的情况,因为3^1是只有一个的也-______________-) 然后很容易的可以想到用三进制的加法类似的方法处理. 由于对于第k位(从后面开始由0开始数)来说只能是1/0,就是要么放3^k(k=0..63),要么不放. 准备工作完成了... 下面说下步骤(185作为例子) a.把输入的数字用3进制表示(-___________-别和我说你不会~) b.处理完是:20212 不过由于求的时候数组是倒过来的,由于这题的特殊性所以直接求完放那(既21202,所 在数组设为bit[]) c.从bit[0]到bit[l-1](l表示数组上限,现在是l=5) 如果第k(k=0...l-1)位上是2,那么就说明必须加上1才能使2->0,(因为右边的重量用3进制表示只有0 和1!所以要把2变1)然后要记的进位,其实后面就是三进制的加法了.如果第k(k=0...l-1)位上是 0/1,那么就不要处理了. d.把c中的所有遇到bit[k]=2的位置入栈,然后输出(题目要求从大到小,如果从小到大就用队列),当然 用个数组标记也可以~ 然后左边盘上的已经完成,输出把,把栈清空了... e.扫描bit(bit已经被你折磨过至少k次了...)遇到1就入栈,然后输出,结束,AC; PS:偶的数组是自己打进去的,太囧了........ 希望大家看的懂也........偶也素新人的说-_____________-
以下是代码:
- #include<iostream>
- #include <stack>
- using namespace std;
- stack<int> q;
- int bit[65];
- char pow3[64][101]={"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 main()
- {
- int l,i,j,k;
- long long n;
- while(scanf("%lld",&n)!=EOF)
- {
- l=0;
- while(n)
- {
- bit[l]=n%3;
- l++;
- n/=3;
- }
- for(i=0;i<l;i++)
- {
- if(bit[i]==2)
- {
- bit[i]=0;
- q.push(i);
- k=1;
- for(j=i+1;j<l;j++)
- if(bit[j]+k<3)
- {
- bit[j]+=k;
- k=0;
- break;
- }
- else
- {
- bit[j]=0;
- k=1;
- }
- if(k)
- bit[l++]=k;
- }
- }
- if(!q.size()) printf("0/n");
- while(!q.empty())
- {
- printf("%s",pow3[q.top()]);
- if(q.size()!=1)
- putchar(' ');
- else
- putchar('/n');
- q.pop();
- }
- for(i=0;i<l;i++)
- if(bit[i])
- q.push(i);
- if(!q.size()) printf("0/n");
- while(!q.empty())
- {
- printf("%s",pow3[q.top()]);
- if(q.size()!=1)
- putchar(' ');
- else
- putchar('/n');
- q.pop();
- }
- }
- return 0;
- }
|