2236: Balance and Poise
Result | TIME Limit | MEMORY Limit | Run Times | AC Times | JUDGE |
---|---|---|---|---|---|
5s | 8192K | 311 | 141 | Standard |
工匠大师Hill打造出一个精致的天平, 对他的徒弟Oren说:“你帮我做一些砝码配套,为了方便携带,砝码数目要尽量少”。
Oren:“好。我将按照2进制的规则打造,也就是1,2,4,8,16等等,这样在称量同等重量下使用的砝码数量最少,只使用7个砝码就可以称量1-127的重量。”Hill:“No, you are wrong”。
Oren:“难道还有更好的方法?2进制是最优的,这一点是可以证明的”
Hill:“如果只允许砝码放在天平的一端,那么你说的是对的,可是并没有人限制我们可以在天平的两端放置砝码。所以可以有更好的 方法。如可以设计砝码重量为1,3,9,27,81,只用5个砝码就可以称量1-121”。
Oren:“原来是3进制,那怎么称重呢? 如100克重量?”
Hill:“在天平的左端放上重物,再放上砝码9,右端放砝码1, 27, 81”。
Oren:“嗯,可这是怎么算出来的呢?”
Hill:“It’s your business”。
现在,作为Oren的朋友,请你设计一个程序来计算在这种砝码下应如何称量。
Input:
输入包括多个整数,每个数n占据一行,代表要称重的重量。0 < n <= 1000000000。Output:
对于每个输入的整数,计算当此重量放置在天平左端时,应如何安排3进制的砝码,使天平平衡。每个结果输出一行,输出格式如例子所示,每个数字后面一个空格,如某一侧没有砝码,则输出0,多个砝码按重量升序排列。Sample Input:
100 30
Sample Output:
9 left, 1 27 81 right. 0 left, 3 27 right.
Problem Source: skywind
This problem is used for contest: 32
Submit / Problem List / Status / Discuss
/*这个代码我看了好久我才明白为什么除3当余1时候放右边,当余2的时候放左边了。
n不停的除3意味着数组从左到右不停的移动当余1时候也就也就意味着原来的n可以分解
出来一个前面那些除3次数个3的乘积。当除3余2时候放左边,而又将n+1再除3是为了
从左右两边同时加上前面那些除3次数个3的乘积。*/
#include<stdio.h>
int store[40];
int main()
{
store[1]=store[0]=store[2]=1;
for(int i=2;store[i-1]<1000000000;i++)
{
store[i]=store[i-1]*3;
}
int n;
int left[20];
int right[20];
int ll,rr;
while(scanf("%d",&n)==1)
{
ll=1;
rr=1;
int k=1;
while(n>0)
{
int t=n%3;
if(t==0)n=n/3;
else
{
if(t==1)
{
right[rr++]=store[k];
n=n/3;
}
else
{
left[ll++]=store[k];
n=(n+1)/3;
}
}
k++;
}
if(ll==1)
printf("0 left, ");
else
{
for(int i=1;i<ll;i++)
printf("%d ",left[i]);
printf("left, ");
}
if(rr==1)
printf("0 right, ");
else
{
for(int i=1;i<rr;i++)
printf("%d ",right[i]);
printf("right.\n");
}
}
return 0;
}
n不停的除3意味着数组从左到右不停的移动当余1时候也就也就意味着原来的n可以分解
出来一个前面那些除3次数个3的乘积。当除3余2时候放左边,而又将n+1再除3是为了
从左右两边同时加上前面那些除3次数个3的乘积。*/
#include<stdio.h>
int store[40];
int main()
{
store[1]=store[0]=store[2]=1;
for(int i=2;store[i-1]<1000000000;i++)
{
store[i]=store[i-1]*3;
}
int n;
int left[20];
int right[20];
int ll,rr;
while(scanf("%d",&n)==1)
{
ll=1;
rr=1;
int k=1;
while(n>0)
{
int t=n%3;
if(t==0)n=n/3;
else
{
if(t==1)
{
right[rr++]=store[k];
n=n/3;
}
else
{
left[ll++]=store[k];
n=(n+1)/3;
}
}
k++;
}
if(ll==1)
printf("0 left, ");
else
{
for(int i=1;i<ll;i++)
printf("%d ",left[i]);
printf("left, ");
}
if(rr==1)
printf("0 right, ");
else
{
for(int i=1;i<rr;i++)
printf("%d ",right[i]);
printf("right.\n");
}
}
return 0;
}