九度oj 题目1080:进制转换

Posted Jason杰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了九度oj 题目1080:进制转换相关的知识,希望对你有一定的参考价值。

题目描述:

将M进制的数X转换为N进制的数输出。

输入:

输入的第一行包括两个整数:M和N(2<=M,N<=36)。
下面的一行输入一个数X,X是M进制的数,现在要求你将M进制的数X转换成N进制的数输出。

输出:

输出X的N进制表示的数。

样例输入:
16 10
F
样例输出:
15
提示:

输入时字母部分为大写,输出时为小写,并且有大数据。

 

这题初看起来另我头疼,考虑不难但是很麻烦

一开始想的比较绕,准备先把任意进制转换成10进制,再转化成n进制,于是写出了下面的代码

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <iostream>
  5 
  6 using namespace std;
  7 
  8 char mnum[1002];
  9 int nnum[1002];
 10 int tnCnt;
 11 
 12 int tnum[1002];
 13 int tCnt;
 14 
 15 int tm[1002];
 16 int tmCnt;
 17 
 18 int tSum[1002];
 19 int tsCnt;
 20 
 21 int tDiv[1002];
 22 int tdCnt;
 23 
 24 int m, n;
 25 
 26 int getV(char a) {
 27     if(a >= 0 && a <= 9) {
 28         return a - 0;
 29     }
 30     else if(a >= a && a <= z) {
 31         return a - a + 10;
 32     }
 33     else if(a >= A && a <= Z) {
 34         return a - A + 10;
 35     }
 36 }
 37 
 38 char putV(int a) {
 39     if(a >= 0 && a <= 9) {
 40         return a + 0;
 41     }
 42     else {
 43         return a - 10 + a;
 44     }
 45 }
 46 
 47 void multiTm() {
 48     int ci = 0;
 49     int j = 0;
 50     for(int i = 0; i < tmCnt; i++) {
 51         int ben = tm[i] * m + ci;
 52         tm[j++] = ben % 10;
 53         ci = ben/10;
 54     }
 55     if(ci != 0) {
 56         tm[j++] = ci;
 57     }
 58     tmCnt = j;
 59 }
 60 
 61 int multi(int a[], int acnt, int b[], int t) {
 62     int ci = 0;
 63     int j = 0;
 64     for(int i = 0; i < acnt; i++) {
 65         int ben = a[i] * t + ci;
 66         b[j++] = ben % 10;
 67         ci = ben/10;
 68     }
 69     if(ci != 0) {
 70         b[j++] = ci;
 71     }
 72     return j;
 73 }
 74 
 75 int add(int a[], int acnt, int b[], int bcnt) {
 76     int p = max(acnt, bcnt);
 77     int j = 0;
 78     int ci = 0;
 79     for(int i = 0; i < p; i++) {
 80         int ben = a[i] + b[i] + ci;
 81         a[j++] = ben % 10;
 82         ci = ben/10;
 83     }
 84     if(ci != 0) {
 85         a[j++] = ci;
 86     }
 87     return j;
 88 }
 89 
 90 int div(int t) {
 91     int j = 0;
 92     int ci = 0;
 93     for(int i = 0; i < tdCnt; i++) {
 94         int ben = ci*10 + tDiv[i];
 95         tDiv[j++] = ben/t;
 96         ci = ben%t;
 97         //printf("%d\n",ci);
 98     }
 99     int state = 0;
100     int p = 0;
101     for(int i = 0; i < j; i++) {
102         if(state == 0 && tDiv[i] != 0) {
103             state = 1;
104             tDiv[p++] = tDiv[i];
105         }
106         else if(state == 1) {
107             tDiv[p++] = tDiv[i];
108         }
109     }
110     tdCnt = p;
111 
112     /*for(int i = 0; i <= tdCnt; i++) {
113         printf("%d",tDiv[i]);
114     }
115     puts("");*/
116 
117     return ci;
118 }
119 
120 int main(int argc, char const *argv[])
121 {
122     while(scanf("%d %d",&m,&n) != EOF) {
123         scanf("%s",mnum);
124         //to-ten
125         int lenm = strlen(mnum);
126         
127         memset(tm, 0, sizeof(tm));
128         tm[0] = 1;
129         tmCnt = 1;
130 
131         memset(tnum, 0, sizeof(tnum));
132         tCnt = 0;
133 
134         for(int i = lenm -1; i >= 0; i--) {
135             int tmp = getV(mnum[i]);
136             memset(tSum, 0, sizeof(tSum));
137             tsCnt = 0;
138             tsCnt = multi(tm, tmCnt, tSum, tmp);
139             tCnt = add(tnum,tCnt,tSum,tsCnt);
140             multiTm();
141         }
142 
143         /*for(int i = tCnt-1; i >= 0; i--) {
144             printf("%d",tnum[i]);
145         }
146         puts("");*/
147         for(int i = tCnt-1; i >= 0; i--) {
148             tDiv[tCnt-i-1] = tnum[i];
149         }
150         tdCnt = tCnt;
151         int j = 0;
152         memset(nnum, 0, sizeof(nnum));
153         while(!(tdCnt == 0 && tDiv[0] == 0)) {
154             nnum[j++] = div(n);
155         }
156         for(int i = j-1; i >= 0; i--) {
157             printf("%c",putV(nnum[i]));
158         }
159         puts("");
160     }    
161     return 0;
162 }

虽然例子能跑出来,但提交答案错误

后来一拍脑门,进制直接除n取余就好了,转化成10进制简直多此一举,于是写出下面代码

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <iostream>
 5  
 6 using namespace std;
 7  
 8 char mnum[1002];
 9  
10  
11 int tDiv[1002];
12 int ds, de;
13  
14 int nnum[1002];
15 int nCnt;
16  
17 int m,n;
18  
19 int getV(char a) {
20     if(a >= 0 && a <= 9) {
21         return a - 0;
22     }
23     else if(a >= A && a <= Z) {
24         return a - A + 10;
25     }
26     else if(a >= a && a <= z) {
27         return a - a + 10;
28     }
29      
30 }
31  
32 char putV(int a) {
33     if(a >= 0 && a <= 9) {
34         return a + 0;
35     }
36     else {
37         return a - 10 + a;
38     }
39 }
40  
41 int div() {
42     int j = 0;
43     int ci = 0;
44     for(int i = 0; i < de; i++) {
45         int ben = ci*m + tDiv[i];
46         tDiv[j++] = ben/n;
47         ci = ben%n;
48     }
49     int i = 0;
50     while(tDiv[i] == 0) {
51         i++;
52     }
53     ds = i;
54     return ci;
55 }
56  
57  
58 int main(int argc, char const *argv[])
59 {
60     while(scanf("%d %d",&m,&n) != EOF) {
61         scanf("%s",mnum);
62         int lenm = strlen(mnum);
63  
64         for(int i = 0; i < lenm; i++) {
65             tDiv[i] = getV(mnum[i]);
66         }
67  
68         ds = 0, de = lenm;
69         tDiv[de] = -1;
70         int j = 0;
71         memset(nnum, 0, sizeof(nnum));
72         while(ds != de) {
73             nnum[j++] = div();
74         }
75         for(int i = j-1; i >= 0; i--) {
76             printf("%c",putV(nnum[i]));
77         }
78         puts("");
79     }
80     return 0;
81 }

虽然通过,但耗时70ms

考虑有没有优化的空间,观察一下div 函数,每回都从0开始除,其实每回应该从ds除就好了。50行也应该从ds开始找,但注意j初值也为ds

另外,输出也可改一下

代码如下

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <iostream>
 5  
 6 using namespace std;
 7  
 8 char mnum[1002];
 9  
10  
11 int tDiv[1002];
12 int ds, de;
13  
14 int nnum[1002];
15 int nCnt;
16  
17 char ans[1002];
18 int m,n;
19  
20 int getV(char a) {
21     if(a >= 0 && a <= 9) {
22         return a - 0;
23     }
24     else if(a >= A && a <= Z) {
25         return a - A + 10;
26     }
27     else if(a >= a && a <= z) {
28         return a - a + 10;
29     }
30      
31 }
32  
33 char putV(int a) {
34     if(a >= 0 && a <= 9) {
35         return a + 0;
36     }
37     else {
38         return a - 10 + a;
39     }
40 }
41  
42 int div() {
43     int j = ds;
44     int ci = 0;
45     for(int i = ds; i < de; i++) {
46         int ben = ci*m + tDiv[i];
47         tDiv[j++] = ben/n;
48         ci = ben%n;
49     }
50     int i = ds;
51     while(tDiv[i] == 0) {
52         i++;
53     }
54     ds = i;
55     return ci;
56 }
57  
58  
59 int main(int argc, char const *argv[])
60 {
61     while(scanf("%d %d",&m,&n) != EOF) {
62         scanf("%s",mnum);
63         int lenm = strlen(mnum);
64  
65         for(int i = 0; i < lenm; i++) {
66             tDiv[i] = getV(mnum[i]);
67         }
68  
69         ds = 0, de = lenm;
70         tDiv[de] = -1;
71         int j = 0;
72         memset(nnum, 0, sizeof(nnum));
73         while(ds != de) {
74             nnum[j++] = div();
75         }
76         int p = 0;
77         for(int i = j-1; i >= 0; i--) {
78             ans[p++] = putV(nnum[i]);
79         }
80         ans[p] = \0;
81         puts(ans);
82     }
83     return 0;
84 }

这样,时间缩短到了30ms

但代码还有优化的空间,即数组的一位不再是一位数字,而可以是多位,这样运算次数会更少。

但比较麻烦,以后再考虑吧

以上是关于九度oj 题目1080:进制转换的主要内容,如果未能解决你的问题,请参考以下文章

九度[1080]进制转换

oj---九度oj----大数---进制转换

九度oj 题目1397:查找数段

九度oj 题目1473:二进制数(stack)

九度oj 题目1466:排列与二进制

九度oj 题目1513:二进制中1的个数