UVA - 11121
Time Limit: 3000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
![Download as PDF Download as PDF](https://i-blog.csdnimg.cn/blog_migrate/2ea975a8d421ce3226c46b0946fd5932.png)
Problem D
Base -2
Input: Standard Input
Output: Standard Output
The creator of the universe works in mysterious ways. But |
Scott Adams
Everyone knows about base-2 (binary) integers and base-10 (decimal) integers, but what about base -2? An integer n written in base -2 is a sequence of digits (b i) , writen right-to-left. Each of which is either 0 or 1 (no negative digits!), and the following equality must hold.
n = b0 + b1(-2) + b2(-2)2 + b3(-2)3 + ...
The cool thing is that every integer (including the negative ones) has a unique base--2representation, with no minus sign required. Your task is to find this representation.
Input
The first line of input gives the number of cases, N (at most 10000). N test cases follow. Each one is a line containing a decimal integer in the range from
-1,000,000,000
to
1,000,000,000
.
Output
For each test case, output one line containing "Case #x:" followed by the same integer, written in base -2 with no leading zeros.
Sample Input Output for Sample Input
4 1 7 -2 0 | Case #1: 1 Case #2: 11011 Case #3: 10 Case #4: 0 |
Problemsetter: Igor Naverniouk
Special Thanks: Shahriar Manzoor
Source
Root :: Prominent Problemsetters :: Igor Naverniouk (Abednego)
Root :: Competitive Programming 2: This increases the lower bound of Programming Contests. Again (Steven & Felix Halim) :: Mathematics :: Ad Hoc Mathematics Problems :: Base Number Variants
Root :: Competitive Programming 3: The New Lower Bound of Programming Contests (Steven & Felix Halim) :: Mathematics :: Ad Hoc Mathematics Problems :: Base Number Variants
题意:数学题,给定一个十进制数转化为-2进制。
这里简单说下一个数模一个负数的过程:
如7模-2,余数为1,得数为-3,即余数为7%2,得数为-(7/2)。
如-3模-2,余数为-1,得数为1,即余数为-3%2,得数为-(-3/2)=-(-(3/2))。
算法:n mod -2 余数可能为-1,0,1,但是不能出现-1,只能有0,1所以将-1变为1,并且商要加1。然后依此迭代直到商为0为止。
不懂?(转)
我们来看一个10进制转2进制,例子1024
第0次迭代,1024/2=512,1024%2=0 , 试一下把512++变为513,那么逆回去就是1026,多了2,其实就是2^1
第1次迭代,512/2=256,512%2=0,试一下把256++变为257,那么逆回去,就是1028,多了4,其实就是2^2
说到这里应该很清晰了,在第i次迭代后商+1,其实相当于原来的数增加了2^(i+1),这个有什么用呢
n = b0 + b1(-2) + b2(-2)2 + b3(-2)3 + ...
当n为正数的时候,第i次迭代的时候余数为-1的话,那么i一定是奇数(因为余数为正为负只和n的正负有关,而n的正负在除-2的过程中是交替变化的,很容易可以知道当i为奇数的时候,n是负数或0,余数是-1或0)那么对应的位置就应该是 -1*(-2)^i=2^i ,如果变为1,则是1*(-2)^i=-2^i ,所以变为1后相当于减少了2*2^i=2^(i+1),减少了的要加回来啊,怎么加,就在第i次迭代后的商+1,上面说了,第i次迭代后商+1,相当于逆回去加了2^(i+1),所以以这个商继续迭代下去,最后得到的-2进制数就会等于原来的n
同理,当n为负数的时候,也是一样的分析
且这个问题可以扩展为转化为任意的负进制。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int n, a;
int ans[50];
scanf("%d", &n);
int cas = 1;
while(n--)
{
scanf("%d", &a);
printf("Case #%d: ", cas++);
if(a == 0)
{
printf("0\n");
continue;
}
int num = -1;
while(a)
{
ans[++num] = a%(-2);
a/=(-2);
if(ans[num] == -1)
{ ans[num] = 1; a++; }
}
for(int i=num; i>=0; i--)
{
printf("%d", ans[i]);
}
printf("\n");
}
return 0;
}
想转化为任意负进制的话,你就只需要把-2改成相应的负数即可。。