传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1887
题意:有两种操作,from-r n代表把一个-r进制下的数字n转换成10进制,to-r n代表把一个10进制下的数字n转化成-r进制。
分析:两种操作中from操作很容易实现,和转换成正进制一样,没什么好说的,而to操作我们首先可以像正常转化一样进行短除法,举个例子:
把15转化为-3进制。短除法并且倒序之后结果为1,-2,0。而我们的进制中是不能出现-2的,所以我们可以这样考虑,-2这位代表的是-3,而1位代表的是9,我们可以把-2这位加上3,这样本来应该是-3*-2=6,变成了-3*1=-3,差值为6-(-3)=9,正好为其前面一位1代表的数,这是在1进一位变成2即可,最后转换完就是2,1,0。
我们可以在做短除法的过程中进行这样的操作,发现余数小于0就让它减去r,同时商加一,最后得到的数列,倒叙就是答案。注意判to的时候如果输入的是0,需要单独输出,在这上wa了一次。
代码:
/* *********************************************** Author :Torrance_ZHANG Created Time :2016/5/2 14:32:09 File Name :ceshi.cpp ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> typedef long long int LL; using namespace std; int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); char op[10]; while(~scanf("%s",op)){ if(!strcmp(op,"end")) break; if(op[0]=='f'){ int r=op[5]-'0'; if(r==1) r=10; r*=-1; char num[100]; scanf("%s",num); int len=strlen(num); int res=0,c=1; for(int i=len-1;i>=0;i--){ res+=c*(num[i]-'0'); c*=r; } printf("%d ",res); } else{ int r=op[3]-'0'; if(r==1) r=10; r*=-1; int num; scanf("%d",&num); if(num==0){ printf("0 "); continue; } int res[50]={0}; int cnt=0; while(num!=0){ int mod=num%r; num/=r; if(mod<0){ mod-=r; num++; } res[cnt++]=mod; } for(int i=cnt-1;i>=0;i--) printf("%d",res[i]); puts(""); } } return 0; }