P1017 - 进制转换

题目:进制转换

题目来源:洛谷P1017

题目描述

将正整数N转换成进制R的数。其中比较棘手的情况是基数R是负数的情况,因为这时用一般的取模运算,得到的的数码范围是[(R+1),0]。但规定此时的数码依然是非负数。

例如:-16的-2进制表示可以作以下运算:
− 16 = 1 ∗ ( − 2 ) 5 + 1 ∗ ( − 2 ) 4 -16=1*(-2)^5+1*(-2)^4 16=1(2)5+1(2)4
即-16的-2进制表示为:11 0000

输入:输入的每行有两个输入数据。
第一个是十进制数 n。 第二个是负进制数的基数 -R。
输出:输出此负进制数及其基数,若此基数超过 10,则参照 16 进制的方式处理。
输入输出实例:输入 30000 -2 输出 30000=11011010101110000(base-2)

题目分析

首先要了解到C++里的 % 运算符的计算方法:r=m%n 是用
r = m − ( m / n ) ∗ n [ 1 ] r= m- (m/n)*n [1] r=m(m/n)n[1]
得到的,注意m/n为整除法。

可以看出:* 如果m是负数,那么r也一定是负数 *

还是用上面的-16作为例子,如果-16的-2进制按上面的[1]式计算,最后得到的结果是:(-1)0000,这时候的数码显然是不符合要求的。

分析运算过程,如果第i位的数码ri为负,(i从0开始算,是基数的次数)此时i一定为偶数。要得到非负数的数码,需要 1*Ri+1去加上 |ri|*Ri,因为i是偶数,Ri+1是负的,运算得到的结果是一样的。

总结:设m/n=q(整除), r=m%n
有(q+1)*n+(r-n)=q*n+n+r-n=q*n+r=m
这个时候的r一定是正的。

代码

#include<iostream>
using namespace std;
void convert(int n, int r);
char charac[20]={0}; //用于大于10进制的输出,由于最大是20进制,所以就开到20个
int main()
{
	int n,r;
	for(int i=0;i<20;i++)//初始化数组
	{
		charac[i]='A'+i;
	}
	cin>>n>>r;
	cout<<n<<"=";
	convert(n,r);
	cout<<"(base"<<r<<")";
	return 0;
}
void convert(int n,int r)
{
	if(n==0)return;//递归出口
	
	int m=n%r;//余数
	if(m<0)	//余数小于0,将n+基数,再取余 
	{
		m=m-r;
		n=n+r;
	}
	
	convert(n/r,r);
	//需要将结果倒序输出,所以先递归后输出。
	if(m>9)
		cout<<charac[m-10];
	else
		cout<<m;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值