码迷,mamicode.com
首页 > 其他好文 > 详细

大数进制转换

时间:2017-11-26 11:15:35      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:namespace   lld   大循环   har   color   clu   main   方法   ace   

给出一个36进制的大数(0-9,A-Z),将其转为10进制并输出。

 

Input输入:36进制的大数,每一位用0-9,A-Z来表示,A表示10,Z表示35。(A的长度 <= 100000)Output输出:该数的10进制表示Sample Input

1AZ

Sample Output

1691

起初做大数据处理的题目,并没有什么功底,就是突然想到可以用数组,所以再次做到这类题时,仍然记得用数组存位,最后倒着输出就好 所以原始是这么写的

超时代码1
#include <iostream>
#include <map>
#include <queue>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define Max 1000001
#define INF 0x3f3f3f3f
using namespace std;
char s[Max];
int ans[Max];
long long index = 0,d;
int main()
{
    scanf("%s",s);
    for(int i = 0;i < strlen(s);i ++)
    {
        if(s[i]>=0&&s[i]<=9)d = s[i] - 0;///每次记录一个位 大循环次数增加
        else d = s[i] - A + 10;

        for(int j = 0;j <= index;j ++)
        {
            d += ans[j] * 36;
            ans[j] = d % 10;///每次存单位数  此处循环次数增加
            d /= 10;
        }
        while(d){ans[++index]=d%10;d/=10;}
    }
    for(int i = index;i >= 0;i --)
    printf("%d",ans[i]);
}

超时就想可不可以减少循环次数,然后就想到一个位可以存多位数,甚至改成long long

然后

超时代码2

#include <iostream>
#include <map>
#include <queue>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define Max 1000001
#define In 1000000000000000
#define INF 0x3f3f3f3f
using namespace std;
char s[Max];
long long ans[Max];
long long index = 0,d = 0;
int main()
{
    scanf("%s",s);
    for(int i = 0;i < strlen(s);i ++)
    {
        if(s[i]>=0&&s[i]<=9)d = s[i] - 0;///这里还没想到要每次取多位
        else d += s[i] - A + 10;
        for(int i = 0;i <= index;i ++)
        {
            d += ans[i] * 36;
            ans[i] = d % In;
            d /= In;
        }
        while(d)
        {
            ans[++ index] = d % In;///做了优化
            d /= In;
        }
    }
    for(int i = index;i >= 0;i --)
    if(i == index)printf("%lld",ans[i]);
    else printf("%015lld",ans[i]);
}

最后才想到能过的方法了

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100000
using namespace std;
const long long In = (long long)1e10;///每一位存的大小界限  不超过1e10
char s[Max];
long long ans[Max];///存十进制转换后的数 每个位不再存10以下的数(也就是单位数) 而是存1e10以下的数
long long index = 0,d = 0;///index为ans下标 总的位数 d 是个辅助变量
const long long e[5] = {36,36*36,36*36*36,36*36*36*36,36*36*36*36*36};///36进制的不同位
int q[300];///转换 char 到 int
void init()///初始字符到int 方便直接使用
{
    for(int i = 0;i <= 9;i ++)
        q[i + 0] = i;
    for(int i = 0;i <= 25;i ++)
        q[i + A] = i + 10;
}
int main()
{
    scanf("%s",s);
    int len = strlen(s),i = 0;
    init();
    while(i < len)
    {
        for(int j = 0;i + j < len && j < 5;j ++)///每次最高读取五个位  然后存到十进制ans数组
        d = d * 36 + q[s[i + j]];

        for(int j = 0;j <= index;j ++)
        {
            d += ans[j] * e[min(len - i - 1,4)];///当前的ans具体要前移几位要看剩下几位要存进来  如果剩下的不足五位 那么就是len - i位 对应于e数组相应值 需要注意e最高是36进制第五位 那么ans每个位不能存过高 不然相乘后会超了 long long
            ans[j] = d % In;
            d /= In;
        }
        if(d)ans[++ index] = d % In,d /= In;///如果d不为0 向前进一位
        i += 5;
    }
    for(int i = index;i >= 0;i --)
    if(i == index)printf("%lld",ans[i]);
    else printf("%010lld",ans[i]);///如果是0 要输出十位
}

 

java BigInteger类 路过

Scanner sc = ...
BigInteger a = sc.nextBigInteger(36);
System.out.print(a);

 

大数进制转换

标签:namespace   lld   大循环   har   color   clu   main   方法   ace   

原文地址:http://www.cnblogs.com/8023spz/p/7898322.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!