• 洛谷千题详解 | P1017 [NOIP2000 提高组] 进制转换【C++、Java、Pascal、Python语言】


    博主主页:Yu·仙笙

    专栏地址:洛谷千题详解

    目录

    题目描述

    输入格式

    输出格式

    输入输出样例

    解析:

    那么怎么把负数转成正数?

    j-=m(j为原先算出来的负数,m为进制数)

    n/m=a

    n-a*m=j

    n-a*m-m=j-m

    n-(a+1)*m=j-m

    n++(此时n已经/=m)

    C++源码:

    Pascal源码:

    Java源码:

    Python源码:


    -------------------------------------------------------------------------------------------------------------------------------- 

    -------------------------------------------------------------------------------------------------------------------------------- 

    题目描述

    我们可以用这样的方式来表示一个十进制数: 将每个阿拉伯数字乘以一个以该数字所处位置为指数,以 10 为底数的幂之和的形式。例如 123 可表示为 1×102+2×101+3×100 这样的形式。

    与之相似的,对二进制数来说,也可表示成每个二进制数码乘以一个以该数字所处位置为指数,以 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,以此类推。

    在负进制数中是用 −R 作为基数,例如 −15(十进制)相当于 110001 (−2进制),并且它可以被表示为 2 的幂级数的和数:

    110001=1×(−2)5+1×(−2)4+0×(−2)3+0×(−2)2+0×(−2)1+1×(−2)0

    设计一个程序,读入一个十进制数和一个负进制数的基数, 并将此十进制数转换为此负进制下的数。

    -------------------------------------------------------------------------------------------------------------------------------- 

    输入格式

    输入的每行有两个输入数据。

    第一个是十进制数 n。 第二个是负进制数的基数−R。

    -------------------------------------------------------------------------------------------------------------------------------- 

    输出格式

    输出此负进制数及其基数,若此基数超过 10,则参照 16 进制的方式处理。

    -------------------------------------------------------------------------------------------------------------------------------- 

    输入输出样例

    输入 #1

    30000 -2

    输出 #1

    30000=11011010101110000(base-2)

    输入 #2

    -20000 -2

    输出 #2

    -20000=1111011000100000(base-2)

    输入 #3

    28800 -16

    输出 #3

    28800=19180(base-16)

    输入 #4

    -25000 -16

    输出 #4

    -25000=7FB8(base-16)

    -------------------------------------------------------------------------------------------------------------------------------- 

    解析:

    我们都知道,首先按照10进制转成n进制的做法:

    对这个数不断除以n,将余数一一存储,最后倒序输出。

    那么有一个问题,此处原数和进制数都有可能为负数,也就意味着余数可能为负数,那么我们不可能输出像-100-100这种数。

    那么怎么把负数转成正数?

    我们基本思路分两点:

    1. 把负数转成符合n进制余数规律的正数
    2. 让转得的正数符合余数的计算模式

    1. 把负数转成符合n进制余数规律的正数

    我们先来探讨一下二进制余数的规律:

    01234567
    01010101
    那么规律就是0101010101……

    那么我们只需让负数余数规律也为010101……,就解决了。

    我们发现,每一组数,他们对应的间隔区间内的数是相等的。那么我们只需跳到它前面一个区间的数即可,因为区间长度为-m,(m为进制)。那么就转换成:

    j-=m(j为原先算出来的负数,m为进制数)

    让转得的正数符合余数的计算模式

    光转成正数还不够,因为还不符合余数的计算。

    众所周知,我们令n为被除数,m为除数和进制数,a为商,j为余数,可以得到:

    n/m=a

    n-a*m=j

    根据我们刚刚推得的算法:j-=m,那么此时方程2两端同时减去m,得

    n-a*m-m=j-m

    提公因式,得

    n-(a+1)*m=j-m

    但我们还要让j-m符合余数计算模式,即符合n-a*m=j的形式。

    显然,此时a=a+1正好符合n-a*m=j的形式。所以:

    n++(此时n已经/=m)

    -------------------------------------------------------------------------------------------------------------------------------- 

    C++源码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. //#include
    15. using namespace std;
    16. //std::ios::sync_with_stdio(false);
    17. #pragma comment(linker, "/STACK:1024000000,1024000000")
    18. #define LL long long
    19. #define ll long long
    20. #define inf 1e-5
    21. const int INF=1<<30;
    22. const int MAX=40000;
    23. const int mod=1e9+7;
    24. int P[20];
    25. char b[100];
    26. char bit[100];
    27. int N,R;
    28. void getBit(){
    29. int i,j,ans;
    30. for(i=0;i<10;i++){
    31. b[i]=i+'0';
    32. }
    33. for(i=0;i<=26;i++){
    34. b[i+10]=i+'A';
    35. }
    36. }
    37. int main(int argc,char *argv[]){
    38. //freopen("in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取
    39. //freopen("out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中
    40. //srand(time(NULL));//有的OJ不能加这句话
    41. int M,i,j,ans,k;
    42. getBit();
    43. while(~scanf("%d%d",&M,&R)){
    44. N=M;
    45. R=abs(R);
    46. memset(bit,0,sizeof(bit));
    47. if(N>0){
    48. for(i=0;N!=0;i++){
    49. k=N%R;
    50. if(i%2==0){
    51. bit[i]=b[k];
    52. N/=R;
    53. }else{
    54. k=k?R-k:0;
    55. bit[i]=b[k];
    56. N=(int)ceil((double)N/(double)R);
    57. }
    58. }
    59. }else{
    60. N=abs(N);
    61. for(i=0;N!=0;i++){
    62. k=N%R;
    63. if(i%2==0){
    64. k=k?R-k:0;
    65. bit[i]=b[k];
    66. N=(int)ceil((double)N/(double)R);
    67. }else{
    68. bit[i]=b[k];
    69. N/=R;
    70. }
    71. }
    72. }
    73. printf("%d=",M);
    74. for(i=strlen(bit)-1;i>=0;i--){
    75. printf("%c",bit[i]);
    76. }
    77. printf("(base-%d)\n",R);
    78. }
    79. return 0;
    80. }

    -------------------------------------------------------------------------------------------------------------------------------- 

    Pascal源码:

    1. var m,n,i,x,y:longint;
    2. s:string;
    3. begin
    4. readln(n,x);
    5. s:='';m:=n;//保存取值
    6. while(m<>0)do
    7. begin
    8. y:=m mod x;
    9. m:=m div x;
    10. if y<0 then
    11. begin
    12. inc(m);
    13. y:=y-x;
    14. end;
    15. if(y<10)then s:=chr(y+48)+s else s:=chr(y+55)+s;
    16. end;
    17. write(n,'=',s,'(base',x,')');
    18. readln;
    19. end.

    -------------------------------------------------------------------------------------------------------------------------------- 

    Java源码:

    1. import java.util.Scanner;
    2. public class P1017 {
    3. public static void main(String[] args) {
    4. Scanner sc = new Scanner(System.in);
    5. final char[] num = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J'};
    6. char[] ans = new char[1000];
    7. int temp, i = 0;
    8. int n = sc.nextInt();
    9. int R = sc.nextInt();
    10. temp = n;
    11. while (n != 0) {
    12. int mod = n % R;
    13. int t = n / R;
    14. if (mod < 0) {
    15. mod -= R;
    16. t++;
    17. }
    18. n = t;
    19. ans[i++] = num[mod];
    20. }
    21. System.out.print(temp + "=");
    22. for (int j = i - 1; j >= 0; j--)
    23. System.out.print(ans[j]);
    24. System.out.print("(base" + R + ")");
    25. }
    26. }

    -------------------------------------------------------------------------------------------------------------------------------- 

    Python源码

    1. """
    2. P1017 [NOIP2000 提高组] 进制转换(python3实现)
    3. https://www.luogu.com.cn/problem/P1017
    4. """
    5. def zhuan(n,r):
    6. if n==0:
    7. return
    8. m=n%r
    9. if m<0:
    10. m-=r
    11. n+=r
    12. if m>=10:
    13. m=m+65-10
    14. else:
    15. m+=48
    16. zhuan(n//r,r)
    17. print(chr(m),end="")
    18. return
    19. ans=""
    20. n,r=map(int,input().split())
    21. print(n,end="=")
    22. zhuan(n,r)
    23. print("(base%d)"%r)

    -------------------------------------------------------------------------------------------------------------------------------- 

  • 相关阅读:
    数据结构之队列
    低代码!小白用10分钟也能利用flowise构建AIGC| 业务问答 | 文本识别 | 网络爬虫
    Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的
    ElasticSearch查询大于10000条的数据
    MyBatis框架简介
    P5682 [CSP-J2019 江西] 次大值% 运算 set 去重的一道好题
    springcloud引入Eureka报错
    libmp4v2不完全指南封装g711a的坑
    Biotin-Dadps-N3,1260247-50-4,DADPS叠氮生物素科研试剂供应
    运维理想和现实,你是?
  • 原文地址:https://blog.csdn.net/djfihhfs/article/details/127769680