【信奥赛C++】第一期:进制转换(基础班)

例1、----------------进制转换------------------------

题目描述

给一个小整数 x x x 和一个 x x x 进制的数 S S S。将 S S S 转为 10 10 10 进制数。对于超过十进制的数码,用 AB … \ldots 表示。

输入格式

第一行一个整数 x x x;

第二行一个字符串 S S S

输出格式

输出仅包含一个整数,表示答案。

样例

样例输入

16
7B

样例输出

123

解析:

1.ConvertToDecimal1实现了将一个字符串数字转化为想要得到的十进制数
2.ConvertToDecimal2实现了将一个int型数字转化为想要得到的十进制数
3.ConvertToDecimal3实现了将一个大于十进制数的数字转化为想要得到的十进制数

//将任意一个n进制数转换为10进制
#include <iostream>
using namespace std;
//string与int 相互转换
int StringToInt(string str){
    int num = 0;
    for (int i = 0; i < str.size(); i++)
    {
        num = num * 10 + str[i] - '0';//将string的每一位乘位阶累加得到总值
    }
    return num;
}
void ConvertToDecimal1(int n, int num)//此函数实现了n进制数num转换为十进制数,利用常规思路
{
    int decimal = 0;//定义要转换的十进制数
    int base = 1;//基础乘阶
    while (num > 0)
    {
        int remainder = num % 10;//n进制数的每一位,从右到左
        decimal += remainder * base;//依次乘相应的位阶
        base *= n;//位阶每左移一位,base累乘乘阶
        num /= 10;//进行下一位的取值
    }
    cout << decimal << endl;
}
void ConvertToDecimal2(int n, int num){
    int ans=0,i=0;
    char str[100];
    while(num > 0){//将num(int型)每一位存放在str字符数组里
        str[i] = num % 10 + '0';//从左到右存放
        num /= 10;
        i++;
    }
    for(int j=i-1;j>=0;j--){
        ans=ans*n+str[j]-'0';//从右到左累加
    }

    cout << ans << endl;
}
void ConvertToDecimal3(int n, string num){//此函数实现了高于十进制的类型转换,利用九章算术进行简化操作
    //可以转化>10进制
    int ans=0;
    for(int j=0;j<num.size();j++){
        if(num[j]>='0' && num[j]<='9'){//此处做一个是否高于十进制的判断
            ans=ans*n+num[j]-'0';
        }else{
            ans=ans*n+num[j]-'A'+10;//若高于十进制则需要得到此数与A(10)的差值,再经过一个+10运算
        }
    }
    cout << ans << endl;
}
void main_convert(){
    int n;
    string num;
    cin>>n>>num;
    if(n>10){
        ConvertToDecimal3(n,num);
    }
    else{
        ConvertToDecimal2(n,StringToInt(num));
    }

}
int main(){
    main_convert();
}

例2、----------------汽车号牌------------------------

题目描述

小 Y 最近发现街上的汽车越来越多了,作为汽车的重要标志——汽车牌照也是越来越不够用了,已经从以前的十进制发展到三十六进制了,以前的一个汽车牌照“苏 D88888”,现在的牌照“苏 D0YY11”。
小 Y 突发其想,想知道他看到的大量汽车牌照中最近的两个汽车牌照相差多少?

输入格式

若干行(不超过 500000 行),每行为一个汽车牌照。

每个汽车牌照为一个 7 位的字符串,格式为 SD×××××,其中一个 × 表示一个 0~9 或A~Z,所涉及的字母均为大写。

输出格式

一行一个数,表示最接近的两个汽车牌照之间的差值,要求为十进制数。

样例

样例输入

SD12345
SD88888
SD22222
SD99999

样例输出

1678245

解析:

首先,将车牌的首字母进行删减,得到5位的36进制数,在对36进制数进行转十进制数,存放再数组中,对数组进行排列,利用哨兵存放间隔最小值,输出即可

#include<bits/stdc++.h>
using namespace std;
int hex36_to_dec(string s) {//车牌号是36进制数,即9个数字+26个字母
    s.erase(0, 2);//删除前两位的字母,是对数字进行处理操作
    int sum = 0;//定义累加和
    for (int i = 0; i < s.size(); i++) {
        if (s[i] >= '0' && s[i] <= '9') {
            sum = sum * 36 + s[i] - '0';//数字仅需乘加操作
        } else if (s[i] >= 'A' && s[i] <= 'Z') {
            sum = sum * 36 + s[i] - 'A' + 10;//字母则需进行求差值操作
        }
    }
    return sum;
}

void main_getDvalue(){
    string s;
    int i=0;
    int a[500000];
    while(getline(cin, s)){
        if (s.size() == 0)
            break;
        int num = hex36_to_dec(s);//转化操作
        a[i]=num;
        i++;
    }
    sort(a,a+i);//从小到大进行排序
    int ans=a[1]-a[0];//利用哨兵,存取最小值
    for (int j = 2; j < i; ++j) {
        if (a[j]-a[j-1]<ans)
            ans=a[j]-a[j-1];//最终得到数组中相差最大的某两个值
    }
    cout<<ans<<endl;
    
}
int main(){
    main_getDvalue();
}

例3、----------------数列--------------------------

题目描述

给定一个正整数 k,把所有 k 的方幂及所有有限个互不相等的 k 的方幂之和构成一个递增的序列,例如,当 k=3 时,这个序列是:

1,3,4,9,10,12,13,…
该序列实际上就是:30,31,30+31,32,30+32,31+32,30+31+32,…
请你求出这个序列的第 N 项的值(N 用 10 进制数表示,从 1 开始)。

例如,对于 k=3,N=100,正确答案应该是 981。

输入格式

输入文件只有 1 行,为 2 个正整数,用一个空格隔开:k,N。

输出格式

输出文件为计算结果,是一个正整数(在所有的测试数据中,结果均不超过 2.1×109)。(整数前不要有空格和其他符号)。

数据范围

3≤k≤15,
10≤N≤1000

输入样例:

3 100

输出样例:

981

解析:

首先利用转二进制可以发现数列中的序号都可转化为二进制数从1开始排列对应表达式的位阶,利用此种特性,我们可以进行累加操作。

#include<bits/stdc++.h>
using namespace std;
void main_getvalue()
{
    int a[100000];
    int k,n,i=0;
    cin>>k>>n;
    while(n){
        a[++i]=n%2;
        n/=2;
    }
    int x=1;
    int ans=a[1];
    for (int j = 2; j <=i ; j++) {
        x*=k;
        ans+=a[j]*x;
    }
    cout<<ans<<endl;
}
int main(){
    main_getvalue();
}
  • 46
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值