本文主要是介绍ATM (负二进制),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Problem Description


在一个银行的大厅里有30个自动柜员机,编号分别为0..29,每个会员顾客都能通过这些柜员机提取10^9 ducats(一种早期的流通硬币单位)的借款业务,但必须在一个星期内还是通过这些柜员机完成还款业务。这种柜员机很特别,每个柜员机只能完成一种简单的动作:供客户提取固定数目的现金或接受客户固定数目的还款。第i个柜员机只能提供2^i ducats的借款业务,如果i是偶数的话;而如果i是奇数的话,则第i个柜员机只能提供2^i ducats的还款业务。
现在,如果有一个客户想要用这些柜员机借一定数目的钱,但是每个柜员机都只能使用一次,那么,他该使用哪些柜员机呢?
一个星期内还款时,他又该使用哪些柜员机呢?
比如,他要借7 ducats,则他会从4号柜员机拿到16 ducats,从0号柜员机拿到1 ducats,再到3号柜员机还掉8 ducats,到1号柜员机还掉2 ducats。
一个星期内还款时,他会到3号柜员机先还掉8 ducats,再到0号柜员机拿到1 ducats。
请你编写一个程序,当一个客户借款,告诉他该使用哪些柜员机,以后还款时又该使用哪些柜员机。
Input
第一行为整数N(N<=1000),表示客户的数目。下面有N行,每行为一个正整数,表示每个客户要借多少钱。注意:每个客户最多能借10^9 ducats。
Output
共2N行,第2i-1行表示客户i借款时该使用哪些柜员机,第2i行表示客户i还款时该使用哪些柜员机(1<=i<=N),每行都要求按柜员机编号从大到小输出,每个编号之间用1个空格隔开。
如果业务无法成交,则输出NIE。
如果业务无法成交,则输出NIE。
Sample Input
2 7 385171980
Sample Output
4 3 1 0 3 0 NIE 29 28 27 24 20 19 18 17 16 15 14 9 5 4 2
所谓的负二进制:3=4-2+1. 7=16-8+0*4-2+1.
这道题目就是问输入一个数字n,分别求n和-n的负二进制表示。
就拿3来说,3%2=1,所以0位是1,然后-3/2=-1, -1%2是1,所以1位是1, 然后 值得注意的地方是 -1不能跟刚才一样处理,要不会得到3位是0的错误结果。
应该是(-1*1+1)/2 。
-n的处理一样。
#include<cstdio>
#include<iostream>
using namespace std;int main()
{int t;int i;int num[40];int n,temp;cin>>t;while(t--){cin>>n;temp=n;for(i=0;temp!=0;i++){num[i]=temp%2;if(num[i]<0)num[i]=-num[i];if(temp<0&&temp%2!=0)temp=(-temp+1)/2;elsetemp=-temp/2;}i--;if(i>=30){cout<<"NIE"<<endl;}else{cout<<i;for(i--;i>=0;i--)if(num[i]!=0)printf(" %d",i);cout<<endl;}temp=-n;for(i=0;temp!=0;i++){num[i]=temp%2;if(num[i]<0)num[i]=-num[i];if(temp<0&&temp%2!=0)temp=(-temp+1)/2;elsetemp=-temp/2;}i--;if(i>=30){cout<<"NIE"<<endl;}else{cout<<i;for(i--;i>=0;i--)if(num[i]!=0)printf(" %d",i);cout<<endl;}}return 0;
}
这篇关于ATM (负二进制)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!