FJNU 2013 王子与公主的游戏_砝码问题

64 篇文章 0 订阅
8 篇文章 0 订阅

王子和公主的游戏

Time Limit: 1 Seconds     Memory Limit: 32768 K

Total Submit:38     Accepted:17


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:偶的数组是自己打进去的,太囧了........

希望大家看的懂也........偶也素新人的说-_____________-

 

以下是代码:

 
  1. #include<iostream> 
  2. #include <stack> 
  3. using namespace std;
  4. stack<int> q;
  5. int bit[65];
  6. 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"};
  7. int main()
  8. {
  9.    int l,i,j,k;
  10.    long long n;
  11.    while(scanf("%lld",&n)!=EOF)
  12.       {
  13.         l=0;
  14.         while(n)
  15.            {
  16.               bit[l]=n%3;
  17.               l++;
  18.               n/=3;
  19.            }
  20.         for(i=0;i<l;i++)
  21.            {
  22.               if(bit[i]==2)
  23.                  {
  24.                     bit[i]=0;
  25.                     q.push(i);
  26.                     k=1;
  27.                     for(j=i+1;j<l;j++)
  28.                       if(bit[j]+k<3)
  29.                       {
  30.                          bit[j]+=k;
  31.                          k=0;
  32.                          break;
  33.                       }
  34.                       else
  35.                          {
  36.                             bit[j]=0;
  37.                             k=1;
  38.                          }
  39.                     if(k)
  40.                       bit[l++]=k;
  41.                  }
  42.            }
  43.         if(!q.size()) printf("0/n");
  44.         while(!q.empty())
  45.            {
  46.               printf("%s",pow3[q.top()]);
  47.                     if(q.size()!=1)
  48.                       putchar(' ');
  49.                     else
  50.                       putchar('/n');
  51.               q.pop();
  52.            }
  53.         for(i=0;i<l;i++)
  54.            if(bit[i])
  55.               q.push(i);
  56.         if(!q.size()) printf("0/n");
  57.         while(!q.empty())
  58.            {
  59.               printf("%s",pow3[q.top()]);
  60.                     if(q.size()!=1)
  61.                       putchar(' ');
  62.                     else
  63.                       putchar('/n');
  64.               q.pop();
  65.            }
  66.       }
  67.    return 0;
  68. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值