【无标题】

/*
    信息学奥赛一本通 1309:【例1.6】回文数(Noip1999)
    洛谷 P1015 [NOIP1999 普及组] 回文数

        题的写法一样,主要是输出内容有些许差别,本文给出信息学的那道解法,洛谷的在输出时些许不同,其余完全一样
    
    高精度
    24/2/20
    
    题意:给定一个n进制数m,经一个操作,求最少几步可得到一个回文数(从左到右读 和 从右到左读 是一样的,如1221),
        若超过30步 则输出“Impossible”。 该操作是:如 m = 23 --> 23 + 32 = 55 ,一步操作。 
     
    思路:一个n进制数 m , 依次取出每位的数字(int num = m%n, m/=n; while(m)循环),再逆向组成一个新数 将两者相加 再重复以上操作,该数的范围可能会超过long long,
            故用字符串存 
    
    心得:没写之前 感觉很简单 按题意步骤来就 ok 
          这道题我写了两天, 最主要的一个问题是我忽略了十六进制可以输入字母,一开始没考虑到,感觉自己没啥问题,后来发现了
          一开始还没想对 总想在16进制时把超过9的数字转为对应的字母 ,后来发现想反了, 应该是把十六进制输入的字母转为对应的数字
          才能做相应的加法 
         
*/
 

#include<iostream>
#include<vector> 
#include<string>
#include<algorithm> 
#include<functional>
using namespace std;

const int steps = 30;
int step;

// n进制 高精度加法 
vector<int> add(vector<int>&A,vector<int>&B, int n){  
    vector<int>C;
    if(A.size() < B.size())
        return add(B,A,n);
    int t = 0;
    for(int i = 0; i < A.size(); i++){
        t += A[i];
        if(i < B.size()) t += B[i];
        C.push_back(t%n);
        t /= n;
    }
    if(t) C.push_back(t);//最后的进位 
    reverse(C.begin(), C.end());
    return C; 
}

//判断是否为回文数
bool isPalin(vector<int>&M){
    for(int i = 0; i < M.size()/2; i++){
        if(M[i] != M[M.size() - 1 - i]){
//            cout << "No" << endl;
            return false;
        } 
    }
//    cout << "Yes" << endl;
    return true;    
}


int getValue(char ch){
    if(ch >= '0' && ch <= '9')
        return(ch- '0');
    else{
        return(ch- 'A' + 10); //把十六进制字母 转为 对应数字 
    }
}

int main(){
    int n;
    cin >> n;
    string m;
    cin >> m;
    vector<int> M;
    for(int i = 0; i < m.size(); i++){
        M.push_back(getValue(m[m.size() - i -1]));
    }
    
    vector<int> W;
    for(vector<int>::iterator it = M.begin(); it != M.end(); ++it){
        W.push_back(*it);
    }
    reverse(W.begin(), W.end());
//    cout << "M:";
//    for(vector<int>::iterator it = M.begin(); it != M.end(); it++){
//        cout << *it << " ";
//    }
//    cout << endl;
//    cout << "W:";
//    for(vector<int>::iterator it = W.begin(); it != W.end(); it++){
//        cout << *it << " ";
//    }
//    cout << endl;
    while(step <= steps && !(isPalin(W)) ){
        step++;
        W = add(M,W,n); 
        M.clear();
        for(vector<int>::iterator it = W.begin(); it != W.end(); ++it){
            M.push_back(*it);
        }
        reverse(M.begin(), M.end());
//        cout << "M+W:";
//        for(vector<int>::iterator it = W.begin(); it != W.end(); it++){
//            cout << *it << " ";
//        }
//        puts("");
    }
    if(step > steps) cout << "Impossible" << endl;
    else cout << step << endl;
        
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值