一道很恶心的题目:负进制(题解)

Description

学习信息学的人都熟悉 2 进制,但有没有人想过 -2 进制!那样的数字就不需要符号了!!

2 进制从低位到高位--即从右向左--的位权是 1、2、4、8、16、....。

-2 进制的从右向左的位权当然就是 1、-2、4、-8、16、....。

-2 进制是可以表示任何整数的。如:

1,110,111,100,101,11010,11011,11000,11001,...表示 1,2,3,4,5,6,7,8,9,....

而11,10,1101,1100,1111,...则表示 -1,-2,-3,-4,-5,....

现在给你一个十进制的整数 n,请求出它的 -2 进制数。

Format

Input

只一行,一个十进制整数 n。

Output

一个 -2 进制数。如果数字不为 0,不能有前导 0。

Samples

输入数据 1

-13

输出数据 1

110111

Explanation

样例一说明:从右向左:1 × 1 + 1 × -2 + 1 × 4 + 0 × -8 + 1 × 16 + 1 × -32 = -13

Limitation

对于 100% 的数据,-2000000000 ≤ n ≤ 2000000000。


 分 析 :

如果还不知道十进制怎么转二进制的话,请看

十进制转二进制(简单)_Phrvth的博客-CSDN博客


这题本质上是和十进制转二进制差不多一样的,但是(不难的话他就不会在这里了)

余数是负数怎么办

例如:我们在把13转换成二进制是:1101,难道,我们转成负进制就变成-1-10-1????显然是不行的!

我们怎么把负数转成二进制呢?

重点:正数和负数规律

#include<bits/stdc++.h>
using namespace std;
int main(){
	for(int i=-10;i<=10;i++){
		cout<<i<<":"<<i%-2<<endl;
	}
	return 0;
}
-10:0
-9:-1
-8:0
-7:-1
-6:0
-5:-1
-4:0
-3:-1
-2:0
-1:-1
0:0
1:1
2:0
3:1
4:0
5:1
6:0
7:1
8:0
9:1
10:0

不难发现

正数0101
负数0-10-1

我们可以发现余数只有在负数和正数为奇数时才不一样,所以直接特判即可

我们把这个加二,还不够,因为还不符合余数的计算,一开始方程得:

n/m = a\cdots j (一开始设n为被除数,m为除数,a为商,j为余数)

n-a*m = j

这时,设m为-2

n - a*m -m = j-m

证明 a-m(m<0) = a+(-m) = a+\left | m \right |

提公因式得 n-(a-1)*m = j-m

原本公式是n-a*m = j

只需要a++就行了

a = n/m

得这两个关系式j+=2 和 n/m+1

得完数之后把数存进数组,倒叙输出(要特判0)

AC完整代码:

#include <bits/stdc++.h>
using namespace std;
int a[2005],n,sum;//变量 
int main() {
	cin>>n;
	if(n==0){//特判 
		cout<<0;
		return 0;
	} 
	while(n!=0){
		int j = n%-2;//等于j 
		n/=-2;//等于a 
		if(j<0)j+=2,n++;//特殊情况 
		a[++sum] = j;//存储 
	}
	for(int i=sum;i>=1;i--){
		cout<<a[i];//倒叙输出 
	}
    return 0;//完结撒花 
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值