我的天,这道题简直就是噩梦,我查了好久好久的资料才看懂题意(没错你没听错看懂题意/暴风哭泣)
大致意思就是说,给你一个整数(可能是正的也可能是负的)和一个你要转换的负进制数的基数(就是你要转换为几进制,不过他是负的)。
思路:跟第一题是一样的,不过用短除法取余然后转换进制可能不可行,因为他的被除数可能是负的,这就直接导致余数也是负的,所以我们就要加个判断:
if(shu[ans]<0){//判断如果这个余数<0 shu[ans]-=m;//就让他减去一个除数,相当于我们在被除数那里借了一个除数 n++;//既然我们在那里借了一个,所以就让他+1 }//这样所有问题就都解决啦
这个判断的作用就是拯救这一切!
原理:因为除数一定是负数,所以如果余数减去除数就会得到一个正整数,那么我们把他减去了,就要把商加一(就相当于从商那里借了一个除数)。
可能这样说会不很形象,我们来放算式看看(因为负数的算式不好理解,所以这里用的正数的算式,理解了正数算式负数算式也就理解了):
15/2=7......1,7=15里面有7个2,也就是说这7里面每个1都表示的是2,那么现在我们大概能理解为什么我们减去一个除数商为什么要加一了吧?
现在我们再用负数算式来套一下,-15/-2=7......-1就可以改成-15/-2=8......1,我们可以来验证一下:8*(-2)=-16,(-16)+1=-15,验证成功。
然后我们就按照上面的思路+平常进制转换的思路写了这个AC代码:
#include<iostream> #include<cstdio> #include<map> #include<algorithm> using namespace std; long long n,m,ha,shu[100010],ans=0,hhh=0; int main(){ cin>>n>>m; hhh=n;//因为我们后面还需要n,但是我们又需要除他,就用一个变量把n保存下来。 while(n!=0){//短除 shu[ans]=n%m;//用一个数组余数存下来 n/=m; if(shu[ans]<0){//这个判断很重要,如果没有他,负数的情况就会很麻烦 shu[ans]-=m; n++; } ans++; } printf("%lld=",hhh); for(int i=ans-1;i>=0;i--){//因为我们是倒着保存的,所以要倒着输出 if(shu[i]>=10){ if(shu[i]==10) printf("A"); else if(shu[i]==11) printf("B"); else if(shu[i]==12) printf("C"); else if(shu[i]==13) printf("D"); else if(shu[i]==14) printf("E"); else if(shu[i]==15) printf("F"); else if(shu[i]==16) printf("G"); else if(shu[i]==17) printf("H"); else if(shu[i]==18) printf("I"); else if(shu[i]==19) printf("J"); else if(shu[i]==20) printf("K");//因为数据中的基数,他是可能会有-20这种情况的,所以这次不是判断到15就结束了,要判断到20. } else printf("%lld",shu[i]); } printf("(base%lld)",m); return 0; }