自动取款机
时间限制 : 1000 msec 内存限制 : 65535 KB
题目描述
ByteLand上的每位居民都有一个自已的银行帐号,帐号上记录了居民的存款金额,以硬币为单位。他们可以用自己的帐号在30台自动取款机上进行取款或付款的操作。这些自动取款机的编号从0到29,每台取款机都有自己的运行特点。当你在编号为i的取款机上进行操作时,若i是偶数,你将从取款机中获得2^i个硬币;若i是奇数,你将付给该取款机2^i个硬币。
假设你要从银行取14枚硬币,那么你可以在第4号取款机上操作,获得16枚硬币,接着在第1号取款机上操作,付出2枚硬币,最终就得到了14枚硬币。
假设你要付给银行7枚硬币,那么你可以在第3号取款机上操作,先付给8枚硬币,接着在第0号取款机上操作,取回1枚硬币,最终你付给银行7枚硬币。注意:由于银行系统的保险措施,每台取款机最多只能被操作一次。现在,L先生将要向银行支取或交纳一定数额的硬币。你能设计出一个方案,对某些取款机进行操作,从面恰好完成L先生的要求。
输入
输入由多行组成,每行表示要取款或付款的数目(正数表示取款,负数表示付款)。
输出
每行输入对应一行输出,按降序输出需要操作的自动取款机号码。
样例输入
14
-7
7
样例输出
4 1
3 0
4 3 1 0
分析
这个式子与整数的二进制表示法非常相似,所不同的只是把2换成了-2。
观察上面的规律,得出商的符号呈交错变化。在程序中可作如下处理:用flag表示当前数的正负,每次除法后改变它的正负。用n记录当前数的绝对值,且当前数变化规律为:
当n为正偶数时,直接除以2;
当n为正奇数时,减1后除以2;
当n为负偶数时,其绝对值直接除以2;
当n为负奇数时,其绝对值加1再除以2。
程序:
#include <iostream>
using namespace std;
int main()
{
int k,n,flag,a[31];
while(cin>>n)
{
flag=(n>0)?1:(-1);
if(n<0) n=-n; //变为绝对值
k=0;
while(n>0)
{
if(flag>0)//n为正整数
{
if(n%2==0)//n为偶数
a[k++]=0;
else
a[k++]=1;
n/=2;
}//n为正整数结束
else //n为负整数
{
if(n%2==0)
{
n/=2;
a[k++]=0;
}
else
{
n=(n+1)/2;
a[k++]=1;
}
} //n为负整数结束
flag=-flag;
}
for(k=k-1;k>=0;k--)
if(a[k]==1)
cout<<k<<" ";
cout<<endl;
}
return 0;
}