回文数-高精度-模拟

练习下类

https://www.luogu.org/problemnew/show/P1015


//#include "stdafx.h"
#include <iostream>
#include <cstring>
using namespace std;


class LINT
{
private :
    char num[200];
    int n;//进制
public :
    LINT(){};
    LINT(int n,char m[]);	//n进制,数m	
    ~LINT();
    bool IsHuiWen();//是否回文,是1
    LINT Reverse();//颠倒
    LINT operator+(const LINT & b);//重载加法运算
    void Print();
    
};
/*
功能:构造函数
输入:进制n,实际数字字符串:m
输出:无
日期:
*/
LINT::LINT(int n, char m[])
{
    this->n=n;
    //strcpy_s(num,strlen(m)+1,m);
    strcpy(num,m);
}
/*
功能:析构函数
输入:无
输出:无
日期:
*/
LINT::~LINT()
{}
/*
功能:输出私有变量,方便测试
输入:
输出:进制n,实际数字字符串:m
日期:
*/
void LINT::Print()
{
    cout<<"进制:"<<n<<" 数字:"<<num<<endl;
}
/*
功能:判断是否回文
输入:无
输出:是回文:返回1,否则0
日期:
*/
bool LINT::IsHuiWen()
{
    int i=0,len=strlen(num);
    while (i<=len/2)
    {
        if (num[i]!=num[len-i-1]) return 0;
        i++;
    }
    return 1;
}
/*
功能:将长整型颠倒输出
输入:无
输出:从右向左输出
日期:
*/
LINT LINT::Reverse()
{
    LINT tmp;
    int i=0,len=strlen(this->num);

    tmp.n = this->n;

    for(i=0;i<len;i++)
    {
        tmp.num[len-i-1] = this->num[i];
    }
    tmp.num[len]='\0';
    return tmp;
}
/*
功能:重载运算符+ 考虑16进制,且认为ab进制相同
输入:LINT a+b
返回: a+b
日期:
*/
LINT LINT::operator+(const LINT&bb)
{
    LINT c;
    LINT b;
    LINT a;
    b= bb;
    a=*this;
    int lena = strlen(a.num);//a的长度
    int lenb = strlen(b.num);
    int minLenAb = lena>lenb?lenb:lena;//两者的最小,从高位向低位求和
    int maxLenAb = lena>lenb?lena:lenb;//max between a and b
    //首先转换成数字,且完成16进制的字符转换
    if (b.n==16)
    {
        for (int i=0; i<lena; i++) 
        {
            if (a.num[i]>='0' && a.num[i]<='9') a.num[i]-='0';
            else if(a.num[i]=='a' || a.num[i]=='A') a.num[i]=10;
            else if(a.num[i]=='b' || a.num[i]=='B') a.num[i]=11;
            else if(a.num[i]=='c' || a.num[i]=='C') a.num[i]=12;
            else if(a.num[i]=='d' || a.num[i]=='D') a.num[i]=13;
            else if(a.num[i]=='e' || a.num[i]=='e') a.num[i]=14;
            else if(a.num[i]=='f' || a.num[i]=='f') a.num[i]=15;
        }
        for (int i=0; i<lenb; i++) 
        {
            if (b.num[i]>='0' && b.num[i]<='9') b.num[i]-='0';
            else if(b.num[i]=='a' || b.num[i]=='A') b.num[i]=10;
            else if(b.num[i]=='b' || b.num[i]=='B') b.num[i]=11;
            else if(b.num[i]=='c' || b.num[i]=='C') b.num[i]=12;
            else if(b.num[i]=='d' || b.num[i]=='D') b.num[i]=13;
            else if(b.num[i]=='e' || b.num[i]=='e') b.num[i]=14;
            else if(b.num[i]=='f' || b.num[i]=='f') b.num[i]=15;
        }
    }
    else
    {
        for (int i=0; i<lena; i++) a.num[i]-='0';
        for (int i=0; i<lenb; i++) b.num[i]-='0';
    }

    //逆向求和
    for (int i=0; i<minLenAb; i++)
    {
        c.num[i] = a.num[lena-1-i]+b.num[lenb-1-i];
    }
    for (int i=minLenAb; i<lena; i++) c.num[i]=a.num[lena-1-i];
    for (int i=minLenAb; i<lenb; i++) c.num[i]=b.num[lenb-1-i];
    //
    c.num[maxLenAb]='\0';
    c.n = b.n;

    int lenc = maxLenAb;//strlen(c.num);
    c.num[lenc]=0;
    //处理进位问题
    for (int i=0; i<lenc; i++)
    {
        int tmp = c.num[i];
        c.num[i] = tmp % c.n;
        c.num[i+1] += tmp / c.n; 
    }
    //处理进位问题
    if (c.num[lenc]==0) c.num[lenc]='\0';
    else {c.num[lenc+1]='\0';lenc++;}
    
    //lenc = strlen(c.num);
    //翻译城字符
    for (int i=0; i<lenc; i++)
    {
        if (c.n != 16)
        {
            c.num[i] += '0';
        }
        else 
        {
            if (c.num[i]>=0 && c.num[i]<=9) c.num[i]+='0';
            else if (c.num[i]==10) c.num[i]='a';
            else if (c.num[i]==11) c.num[i]='b';
            else if (c.num[i]==12) c.num[i]='c';
            else if (c.num[i]==13) c.num[i]='d';
            else if (c.num[i]==14) c.num[i]='e';
            else if (c.num[i]==15) c.num[i]='f';
        }
    }
    //调到
    
    return c.Reverse();
}
/*
功能:重载运算符+ 没有考虑16进制 只对了3个点 还有1个点
输入:LINT a
返回:LINT a+b后的值
日期:
*/
/*
LINT LINT::operator+(const LINT & b)
{
    LINT c;
    int lena = strlen(this->num);
    int lenb = strlen(b.num);
    int lenc = lena>lenb ? lenb : lena;
    for (int i=0; i<lenc; i++)//从低位加起
    {
        c.num[i] =  b.num[lenb-1-i]+this->num[lena-1-i]-'0';
    }

    for (int i=lenc; i<lena; i++)
    {
        c.num[i] = this->num[lena-1-i];
    }
    for (int i=lenc; i<lenb; i++)
    {
        c.num[i] = b.num[lenb-1-i];
    }
    
    
    if(lena>lenb) c.num[lena] = '\0';
    else c.num[lenb] = '\0';

    c.n = b.n;
    //处理针对n进制,这里因为a,b都是n进制,不做进制转换了
    lenc = strlen(c.num);
    c.num[lenc]='0';
    for (int i=0;i<lenc;i++)
    {
        int tmp = c.num[i]-'0';
        c.num[i] = tmp % c.n+'0';
        c.num[i+1] += tmp / c.n;
    }
    if (c.num[lenc]=='0') c.num[lenc]='\0';
    else c.num[lenc+1]='\0';

    
    c=c.Reverse();
    return c;
}
*/



int main()
{
    int n;
    char num[150];
    int i,j,k;
    cin>>n;
    cin>>num;
    
    LINT a(n,num);

    if (a.IsHuiWen()) {cout<<"STEP=0";return 0;}

    for (k=1;k<=30; k++)
    {
        LINT b = a.Reverse();
        a = a+b;
    //	a.Print();
        if (a.IsHuiWen())break;

    }

    if (k<=30) {cout<<"STEP="<<k;}
    else cout<<"Impossible!";
//	system("pause");
    

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值