WOJ1316-负权数

当我们写一个十进制正数时,其值可以用各位的数码乘以10的幂来表示。例如: 
123 = 1×10^2 + 2×10^1 + 3×10^0 
  一般来说,对于R进制数N,其绝对值可以用各位的数码乘以R的幂: 
N = a[n]×R^(n) + a[n-1]×R^(n-1) + ... + a[0]×R^(0) 
来表示。这里的R可以是正书也可以是负数。当R是负数时,我们称之为负权数。不论R是正数还是负数,我们都采用{0,1,...,|R|-1}这R个数码来表示R进制数各个位。如果|R|>10,我们还将使用大写字母表示数码。例如,对16进制数来说,A表示10(十进制),B表示11(十进制),??,F表示15(十进制)。 
  使用负权数的一个好处就是在表示负数时,我们不需要用到负号?-?。举例来说,10进制数-15用-2进制数来表示就是110001 : 
-15 = 1×(-2)^5 + 1×(-2)^4 + 0×(-2)^3 + 0×(-2)^2 + 0×(-2)^1 + 1×(-2)^0 

输入格式

输入数据有多组,以一行 0 0 结束。

输出格式

读入10进制数和负数R,输出这个10进制数的R进制的形式。

样例输入

 30000 -2
 -20000 -2
28800 -16
-25000 -16
0 0

样例输出

11011010101110000
1111011000100000
19180
7FB8


/*对于一个正数,我们可以先转换为R进制数,再将R进制数转化为-R进制数。知道这种办法,
后面就好办了:对于奇数位(从后面数),-R与R进制代表的值是一样的,对于偶数位,可
以用高位减当前位表示(如:(-R)^3 * a = (-R)^4 – R^3 * (R-a))。*/
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
int main(){
    int n,r,tmp,k,tag,i;
    int a[102];
    while (scanf("%d %d",&n,&r)!=EOF){        
        if(n==0&&r==0) break;
        if(n==0)// 0 is special
        {
            printf("0\n");
            continue;
        }
        r*=-1;
        //label the number: a negative or positive number
        tag=1;
        if(n<0){
            tag=0;
            n*=-1;
        }
        //translate a decimal number into R-representation number
        k=0;
        memset(a,0,sizeof(a));
        while(n!=0){
            tmp=n%r;
            a[k++]=tmp;
            n/=r;
        }
        //translate a R-representation number into a -R-representation number
        i=0;
        while(i<k||a[i]){
            if(a[i]>=r){
                a[i]%=r;
                a[i+1]++;
            }
            if(i%2==tag&&a[i]){
                a[i]=r-a[i];
                a[i+1]++;
            }
            i++;
        }
        //output the answer
        for(i=i-1;i>=0;i--){
            if(a[i]>9) printf("%c",'A'+a[i]-10);
            else printf("%d",a[i]);
        }
        printf("\n");
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/lxq1071717521/article/details/77921536
今日推荐