Acwing 1501. 回文数 (高精度※)

 使用long long 或者 unsigned long long,总是有2个点过不去!

#include <iostream>
#include <stdlib.h>
#include <sstream>
#include <cstdint> 
using namespace std;

int judgehui(long long  a)
{
    string am=to_string(a);
    int len=am.length();
    for(int i=0;i<len;i++)
    {
        if(am[i]!=am[len-i-1])
        {
            return 0;
        }
    }
    return 1;

}

__int128  exchange(long long  a)
{
    string am=to_string(a);
    string dao;
    int len=am.size();
    int i=0;
    for(i=len-1;i>=0;i--)
    {
        dao+=am[i];
    }
    //return atoi(dao.c_str()); no use
    istringstream is(dao);
    long long  m;
    is>>m;
    return m;// 返回倒置的数字
}

int main ()
{
    long long num;
    cin>>num;
    int time;
    cin>>time;
    int trutime=0;
    for(int i=0;i<time;i++)
    {
        if (!judgehui(num))
        {
            trutime++;
            num+=exchange(num);
        }
    }
    cout<<num<<endl;
    cout<<trutime;
}

 

 

由此可见错误就在精度上!

#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef vector<int> vi;
vi add(vi & a, vi & b)
{
    vi ans;
    int t = 0;
    for (int i = 0; i < a.size() || i < b.size(); i ++)
    {
        if (i < a.size()) t += a[i];
        if (i < b.size()) t += b[i];
        ans.push_back(t % 10);
        t /= 10;
    }
    if (t) ans.push_back(t);
    return ans;
}
bool is_s(vi a, vi b)
{
    if (a.size() != b.size()) return false;
    for (int i = 0; i < a.size(); i ++)
        if (a[i] != b[i])
            return false;
    return true;
}
bool is_pa(vi a)
{
    vi b = a;
    reverse(a.begin(), a.end());
    return a == b;
}
int main()
{
    vi n;
    int k;
    string in;
    cin >> in >> k;
    for (int i = in.size() - 1; i >= 0; i --) n.push_back(in[i] - '0');
    for (int i = 0; i < k; i ++)
    {
        if (is_pa(n))
        {
            for (int i = 0; i < n.size(); i ++) cout << n[i];
            cout << endl << i;
            return 0;
        }
        vi m = n;
        reverse(m.begin(), m.end());
        n = add(n, m);
    }
    for (int i = n.size() - 1; i >= 0; i --) cout << n[i];
    cout << endl << k;
}

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

 

思路:
1.把传入的数据用unsigned long long 来存储,因为传入的数据可能很大。
2.把这个数据变成vector<int>数据类型 s,s是倒序的,因为如果是回文数,倒序是相同的,不是回文数的话:进行正序和倒序的相加处理,
并且大数相加的时候我们获得的结果也是倒序,所以s直接用倒序存储,输出的时候情况就会相同。
3. 然后如果不是回文数我们就把逆序和正序进行大数相加,直到次数到达上限K为止。

#include <iostream>
#include <vector>
using namespace std;
typedef   long long ULL;
ULL n,k,res;

bool isCycle(vector<int> s){ // 判断是否是回文数
    int i = 0, j = s.size() - 1;  
    for(; i< j;){  //直接从头尾开始用双指针判断,i>j的时候结束,有不相等的直接返回false。
        if(s[i] == s[j]){
            i++;
            j--;
        }else return false;
    }
    if(i > j) return true;
}
vector<int> addBig(vector<int> &A,vector<int> & B){ // 大数加法,因为这道题目的数据没有限制
    vector<int> C; //不懂大数相加的去看看大数加法
    int t = 0;
    for(int i = 0; i < A.size() || i< B.size();i++){
        if(i < A.size()) t += A[i];
        if(i < B.size()) t +=B[i];
        C.push_back(t % 10);
        t/=10;
    }
    if(t) C.push_back(t);
    return C;
}
vector<int> add(vector<int> s){  // 用A,B保存s的正序和倒序数字,然后进行大数的相加,最后返回C即可
    vector<int> A,B;
    for(int i = s.size() - 1,j = 0;i>=0;i--,j++){//把s的正序和倒序存储在vector里面,这样数据多大都不会溢出
        A.push_back(s[i]);
        B.push_back(s[j]);
    }
    auto C = addBig(A,B);
    return C;
}
int main(){
    cin>>n>>k;
    vector<int> s;
    while(n){  //把n处理成字符串,也许to_string函数也可以
        s.push_back(n%10);
        n /=10;
    }
    if(s.size()==1){//长度为1直接返回
        cout<<s[0]<<endl<<res;
        return 0;
    }
    while(k>res){
        if(isCycle(s)){ 
            for(int i = s.size() - 1; i >=0;i--)cout<<s[i];//这里的地方s需要倒着输出,因为大数的结果我们把个位存储在低位
            cout<<endl<<res;
            return 0;
        }else{
            s = add(s);   // 这里是更新s字符串的值,返回的是大数相加的结果
            res++;
        }
    }
    for(int i = s.size() - 1; i >=0;i--){ //次数到达上线也不是回文数,直接输出
                cout<<s[i];
    }
    cout<<endl<<k;
    return 0;
}

作者:橘味侬糖bioce
链接:https://www.acwing.com/solution/content/69511/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



 就完事了!👆,待更新~

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值