题目传送门
题目大意:
给你一个十进制的数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<<')';
}