HDU 1887 Weird Numbers(负数的进制转化)

  题目要求有两种情况,第一种from情况,正常输出即可,很简单.第二种是to情况,给一个数字,输出负进制R的原码,这个有点小麻烦...解决方法如下;

首先,把这个数n按正常方式展开,形式如下:

  .....(n/R^k) % R, (n/R^k-1) % R , (n/R^k-2) % R,......(n/R^2) % R , (n/R^1) % R , n % R;

    R^(k)      R^(k-1)      R^(k-2)      R^2      R^1    R^0

  (上下对应位相乘得n);

  但是我们这样展开如果直接输出是不可以的,因为这里面有可能有负数,不满足题目的要求,我们做如下处理:假设(n/R^k) % R是负的,我们给他加上-R(注意R为负数),使他变成(n/R^k) % R- R;

(n/R^k) % R - R一定是正数,我们发现新得到的这个数正好比原来的数大R^(K+1),所以我们只要再高一位的位置上加1就可以了,每次遇到负数,都做这样的处理,最后输出的就是正确的答案了!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
    char a[20],b[20];
    int num,R;
    while(~scanf("%s",a))
    {
        if(a[0] == 'e') return 0;
        int lena = strlen(a);
        if(a[lena-1] == '0') R = -10;
        else R = -(a[lena-1] - '0');
        if(a[0] == 'f')
        {
            scanf("%s",b);
            int lenb = strlen(b),ans = 0;
            for(int i = lenb-1; i >= 0; i--)
            {
                ans += powl(R,lenb-1-i)*(b[i] - '0');
            }
            printf("%d
",ans);
        }
        else
        {
            scanf("%d",&num);
            if(!num)
            {
                puts("0");
                continue;
            }
            int res[20],tot = 0;
            memset(res,0,sizeof(res));
            while(num)
            {
                int mod = num % R;
                num /= R;
                if(mod < 0)
                {
                    mod += (-R);
                    num++;
                }
                res[tot++] = mod;
            }
            for(int i = tot-1;i >= 0;i--) printf("%d",res[i]);
            puts("");
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/jifahu/p/5453435.html