第三章 进位制

1010.进位制 **

在这里插入图片描述

  • 题意是给定一个数的进制枚举另一个数可能与他相等的进制
  • 注意这个进制有下界没有上界 即如果最大数字是9 那么他至少是十进制,最大是zzz...zzz(10个z)能表示的最大数的进制 应该是36 ^ 10-1~=3 ^15 longlong 可以存下20位左右
  • 这样顺序枚举进制一定会超时,所以我们使用二分的方法
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

typedef long long LL;

int get(char c){              //字符串转对应整数
    
    if(c<='9')return c-'0';
    
    else return c-'a'+10;
}

LL calc(string s, LL radix){   //二分时radix可能会超出int范围
    
    LL res=0;
    
    for(int i=0;i<s.size();i++){
        
        if(((double)res*radix+get(s[i]))>1e16)return 1e18;   //如果res大于1e16则一定无解,返回较大的数
        
        res=res*radix+get(s[i]);
    }
    
    return res;
}

int main(){
    
    string s1,s2;
    
    int tag,rad;
    
    cin>>s1>>s2>>tag>>rad;
    
    if(tag==2)swap(s1,s2);
    
    LL target=calc(s1,rad);
    
    LL l=0,r=max(target,36LL);         //target较小时,直接取36作为二分上界
    
    for(auto it:s2)l=max(l,get(it)+1LL);    //找出下界
    
    while(l<r){
        
        LL mid=l+r>>1;
        
        if(calc(s2,mid)>=target)r=mid;
        
        else l=mid+1;
    }
    
    if(calc(s2,r)!=target) cout<<"Impossible";
    
    else cout<<r;
}

1015.可逆质数

在这里插入图片描述

  • 需要特判一下1不是质数
  • 注意可以用到cin>>n,n>0逗号表达式简化代码
  • 10进制转其他进制可能会存不下,用longlong 存数,转最多的二进制大概在15位左右

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

typedef long long LL;

vector<int> ten_radix(int n,int radix){
    
    vector<int> res;
    
    while(n){
        
        res.push_back(n%radix);
        
        n/=radix;
    }
    
    if(n)res.push_back(n);
    
    return res;
}

int radix_ten(vector<int> n,int rad){
    
    int res=0;
    
    for(int i=0;i<n.size();i++)res=res*rad+n[i];
    
    return res;
}

bool check(int n){
    
    if(n==1)return false;
    
    for(int i=2;i<=n/i;i++){
        
        if(n%i==0)return false;
    }
    
    return true;
}

int main(){

    int n1,rad;
    
    while(cin>>n1>>rad,n1>=1){
        
        vector<int> n2= ten_radix(n1,rad);
        
        int target= radix_ten(n2,rad);
        
        if(check(n1)&&check(target))cout<<"Yes"<<endl;
        
        else cout<<"No"<<endl;
    }
    
}

1027.火星颜色

在这里插入图片描述

#include<iostream>
#include<cstring>
#include<vector>

using namespace  std;

char get(int x){
    
    if(x<=9)return x+'0';
    
    else return x-10+'A';
}

string change(int n){
    
    vector<char> c;
    
    while(n){
        
        c.push_back(get(n%13));
        
        n=n/13;
    }
    
    if(n)c.push_back(get(n));
    
    while(c.size()<2)c.push_back(0+'0');     //少于两位要补零
    
    string res;
    
    for(int i=c.size()-1;i>=0;i--)res+=c[i];
    
    return res;
}

int main(){
    
    int n1,n2,n3;
    
    cin>>n1>>n2>>n3;
    
    cout<<"#";
    
    cout<<change(n1)<<change(n2)<<change(n3);
}

//y 总果然写的还是简单多了qwq
#include <iostream>

using namespace std;

char get(int x)
{
    if (x <= 9) return '0' + x;
    return 'A' + x - 10;
}

int main()
{
    int a[3];
    for (int i = 0; i < 3; i ++ ) scanf("%d", &a[i]);

    cout << '#';

    for (int i = 0; i < 3; i ++ ) cout << get(a[i] / 13) << get(a[i] % 13);

    return 0;
}

作者:yxc
链接:https://www.acwing.com/activity/content/code/content/269939/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

1100.火星数字(sstream)

在这里插入图片描述

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

char  num[][5]={ "tret","jan","feb","mar","apr","may","jun","jly","aug","sep","oct","nov","dec",
    "tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mer","jou"};

int get(string s){
    
    for(int i=0;i<26;i++){
        
        if(s==num[i]){
            
            if(i<13)return i;
            
            else return (i-12)*13;
        }
    }
    
    return 0;
}

int main(){
    
    int n;
    
    cin>>n;
    
    getchar();              //读掉末尾的换行
    
    while(n--){
        
        string s;
        
        getline(cin,s);
        
        if(s[0]<='9'){
            
            int x=stoi(s);
            
            int high=x/13,low=x%13;    //因为某位是0的时候不用输出,所以这里麻烦点
            
            if(high){
                
                if(low)cout<<num[x/13+12]<<" "<<num[x%13]<<endl;
                
                else cout<<num[x/13+12]<<endl;
            }
            
            else cout<<num[x%13]<<endl;
        }
        else {
            
            int k=s.find(' ');
            
            int res=get(s.substr(0,k));
            
            if(k!=-1)res+=get(s.substr(k+1));
            
            cout<<res<<endl;
        }
    }
}


//sstream操作下的解题方法


#include <iostream>
#include <sstream>

using namespace std;

char names[][5] = {
    "tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec",
    "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou",
};

int get(string word)
{
    for (int i = 0; i < 25; i ++ )
        if (names[i] == word)
        {
            if (i < 13) return i;
            return (i - 12) * 13;
        }
    return -1;  // 一定不会执行
}

int main()
{
    int n;
    cin >> n;
    getchar();

    while (n -- )
    {
        string line;
        getline(cin, line);

        stringstream ssin(line);
        if (line[0] <= '9')
        {
            int v;
            ssin >> v;
            if (v < 13) cout << names[v] << endl;
            else
            {
                cout << names[12 + v / 13];
                if (v % 13 == 0) cout << endl;
                else cout << ' ' << names[v % 13] << endl;
            }
        }
        else
        {
            int res = 0;
            string word;
            while (ssin >> word) res += get(word);
            cout << res << endl;
        }
    }

    return 0;
}

作者:yxc
链接:https://www.acwing.com/activity/content/code/content/269965/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

1019.普通回文数

在这里插入图片描述

  • 注意特判0这种特殊情况
#include<iostream>
#include<cstring>
#include<vector>

using namespace std;

//转化成b进制
vector<int> change_b(int n,int b){
    
    if(!n)return {0};       //如果是0,直接返回{0}即可
    
    vector<int> res;
    
    while(n){
        
        res.push_back(n%b);
        
        n=n/b;
    }

    return res;
}

//检查是否为回文数
bool check(vector<int> c){
    
    for(int i=0, j=c.size()-1;i<j;i++,j--)
        
        if(c[i]!=c[j])return false;
    
    
    return true;
}

int main(){
    
    int n,b;
    
    cin>>n>>b;
    
    vector<int> res=change_b(n,b);
    
    if(check(res))cout<<"Yes"<<endl;
    
    else cout<<"No"<<endl;
    
    cout<<res[res.size()-1];
    
    for(int i=res.size()-2;i>=0;i--)cout<<" "<<res[i];
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值