进制转换(正进制、负进制)

题目传送门

题目大意:
给你一个十进制的数n(可能小于0),让你转换成r进制的数(r也可能小于0)。

如果对于n、r都大于0的情况,那很好考虑,直接用短除法把每一位存起来就行。
短除法

    int cnt=0;
    while(n)
    {
        a[cnt++]=n%r;
        n/=r;
    }

然而这里,我们并不能这样做,因为负数取模有可能得到负数,比如-15%-2==-1,-15/-2==7。我们必须要让余数是正数才能作为一个新进制数的一个位,假设被除数是n,除数是r,商是s,余数是m。
那么有n=s*r+m,对于m小于0时,我们只需(+/-)r,就可以把余数变为正,与此同时,s也需要做出改变,具体加减看r的符号。
这里我们以r为负来看,如果我们要把余数变为正,那么要减去一个r,设新的商为x,那么n=x*r+(m-r),很轻易的发现,xr-r=sr;所以x=s+1

上代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
const int eps=1e-6;
typedef long long ll;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
//#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
void add(string &s,int tt)
{
    if(tt<10)
        s+=tt+'0';
    else
        s+=tt-10+'A';
}
signed main()
{
    IOS;
    int n,r;
    cin>>n>>r;
    string s;
    int m=n;
    while(n)
    {
        if(n%r<0)
        {
            int tt=n%r-r;
            add(s,tt);
            n=n/r+1;
        }
        else
        {
            add(s,n%r);
            n/=r;
        }
    }
    reverse(s.begin(),s.end());
    cout<<m<<'=';
    for(int i=0;i<s.size();i++)
        cout<<s[i];
    cout<<"(base"<<r<<')';
}

发布了93 篇原创文章 · 获赞 9 · 访问量 4203

猜你喜欢

转载自blog.csdn.net/Joker_He/article/details/104784349