Eva's Balance
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 3351 | Accepted: 1680 |
Description
Eva has a balance with 20 poises. The weights of the poises are 1, 3, 9, 27,...,3^19. Eva asserts that she has a way to measure any object whose weight is an integer from 1 to (3^20-1)/2. Assuming that Eva has placed an object with the weight in this range on the left tray of the balance, your task is to place the proper poises on the proper trays so as to weigh the object out.
Input
The first line is an integer T (1 <= T <= 20), which shows the number of the test cases. Each of the following T lines contains an integer W (1 <= W <= (3^20-1)/2), expressing the weight of an object.
Output
For each test case print a line, showing the weights of the poises on the left tray and the right tray. Use a space to separate the left tray and the right tray. The poises on the same tray are arranged in the increasing order, and a comma separates every two of them. If there is no poise on the tray, output "empty".
Sample Input
3 9 5 20
Sample Output
empty 9 1,3 9 1,9 3,27
题意:
天平砝码放置,有重量为1、3、9、27、81 .. 3^K... 3^19 砝码,天平左边给定一个重量值w (1=< w <= (3^20-1)/2 ),求如何摆放砝码使天平两端达到平衡。
分析:
举例分析,以11为例。对于砝码1、3、9、27... ,首先要选择一个接近11的砝码来减少多余权重。若选择27,则remain=27-11=16>1+3+9,显然是不可取的。而如果为初始重量为15,选择9不行,因为15>1+3+9,要选择27,剩下12可以用3+9平衡。注意观察选择临近值的规律,若用a0、a1、a2、a3、a4、a5 来表示砝码重量(aK=3^K),给定w值 a2<w<a3 。若w>a0+a1+a2 则临近值选择a3,若w<=a0+a1+a2临近值选择a2。并设置一个bool值来标识天平哪边偏重些。
程序源代码如下:
#include <iostream>
using namespace std;
#define Right_Bigger 1
#define Left_Bigger 0
int leftTray[100],rightTray[100];
int getClose(int w,int &c)
{
int i,sum=0;
for(i=0;i<20;i++)
{
if(w==c)return 2; //w 为 3的指数
else if(w<=c+sum)
{
if(w>c) return 0; //c为略小于w 的 3的指数
else return 1; //c 为略大于w的 3的指数
}
sum=sum+c;
c=c*3;
}
return 1; //不应该执行到这里
}
void calculate(int remain,bool BiggerSide)
{
int close=1;
int res=getClose(remain,close);
if(res==2)
{
if(BiggerSide==Left_Bigger)
{
rightTray[0]++;
rightTray[rightTray[0]]=remain;
}else
{
leftTray[0]++;
leftTray[leftTray[0]]=remain;
}
}else
{
if(BiggerSide==Left_Bigger)
{
rightTray[0]++;
rightTray[rightTray[0]]=close;
}else
{
leftTray[0]++;
leftTray[leftTray[0]]=close;
}
if(res==1) //close > w
calculate(close-remain,!BiggerSide);
else calculate(remain-close,BiggerSide);
}
}
int main()
{
freopen("in.txt","r",stdin);
int t,w;
cin>>t;
int i,j,r,close;
for(i=0;i<t;i++)
{
cin>>w;
memset(leftTray,0,sizeof(leftTray));
memset(rightTray,0,sizeof(rightTray));
close=1;
r=getClose(w,close);
if(r==2)
{
cout<<"empty "<<w<<endl;
continue;
}else
{
rightTray[0]++;
rightTray[rightTray[0]]=close;
if(r==1)
{
calculate(close-w,Right_Bigger);
}else
{
calculate(w-close,Left_Bigger);
}
}
//显示。。
if(leftTray[0]==0)cout<<"empty ";
else
{
for(j=leftTray[0];j>1;j--)
{
cout<<leftTray[j]<<",";
}
cout<<leftTray[j]<<" ";
}
for(j=rightTray[0];j>1;j--)
{
cout<<rightTray[j]<<",";
}
cout<<rightTray[j]<<endl;
}
return 0;
}