題目背景
NOIP2000提高組 T1
洛谷1017
題目描述
我們可以用這樣的方式來表示一個十進制數:將每個阿拉伯數字乘以一個以該數字所處位置的(值減 1)爲指數,以 10 爲底數的冪之和的形式。例如,123 可表示爲
與之相似的,對二進制數來說,也可表示成每個二進制數碼乘以一個以該數字所處位置的(值-1)爲指數,以 2 爲底數的冪之和的形式。
一般說來,任何一個正整數 R 或一個負整數 -R 都可以被選來作爲一個數制系統的基數。如果是以 R 或 -R 爲基數,則需要用到的數碼爲 0,1,…,R-1。例如,當 R=7 時,所需用到的數碼是 0,1,2, 3,4,5 和 6,這與其是 R 或 -R 無關。如果作爲基數的數絕對值超過 10,則爲了表示這些數碼,通常使用英文字母來表示那些大於 9 的數碼。例如對 16 進制數來說,用 A 表示 10,用 B 表示 11,用 C 表示 12,用 D 表示 13,用 E 表示 14,用 F 表示 15。 在負進制數中是用 -R 作爲基數,例如 -15(+進制)相當於 110001(-2進制),並且它可以被表示爲 2 的冪級數的和數:
問題求解: 設計一個程序,讀入一個十進制數的基數和一個負進制數的基數,並將此十進制數轉換爲此負進制下的數:-R∈{-2,-3,-4,…,-20}
輸入格式
輸入只有一行,是兩個整數。
第一個是十進制數 N(-32768<=N<=32767), 第二個是負進制數的基數 -R。
輸出格式
輸出此負進制數,若此基數超過 10,則參照 16 進制的方式處理。
樣例數據1
輸入
30000 -2
輸出
11011010101110000
樣例數據2
輸入
-20000 -2
輸出
1111011000100000
樣例數據3
輸入
28800 -16
輸出
19180
樣例數據4
輸入
-25000 -16
輸出
7FB8
注:洛谷輸出有所不同。
分析:正如題目,這是一道進制轉換題。不要看到負數就被嚇到,其實進制轉換的通法就是不斷除以進制數存下餘數最後逆向輸出,只是這道題無法保證餘數是正數,我們需要特判,如果<0就把除法答案+1,餘數再減一個進制數(因爲進制數是負數,所以相當於加上了一個正數),如果還不理解,就試一試題目描述中-15和-2的例子吧:
so easy!
代碼
根據洛谷的輸出寫的代碼
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#include<queue>
#include<set>
using namespace std;
int getint()
{
int sum=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
if(ch=='-')
{
f=-1;
ch=getchar();
}
for(;isdigit(ch);ch=getchar())
sum=(sum<<3)+(sum<<1)+ch-48;
return sum*f;
}
int n,nn,r,rr,cnt;
int a[100];
int main()
{
freopen("change.in","r",stdin);
freopen("change.out","w",stdout);
n=getint(),r=getint();
nn=n,rr=r;
while(n)
{
a[++cnt]=n%r;
if(a[cnt]<0)//特判
{
a[cnt]-=r;
n=n/r+1;
}
else
n=n/r;
}
printf("%d=",nn);
for(int i=cnt;i>=1;--i)
{
if(a[i]>=10)
printf("%c",'A'+a[i]-10);
else
cout<<a[i];
}
printf("(base%d)",rr);
return 0;
}
本題結。