Vijos P1304 回文数【回文+进制】

描述

若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。

例如:给定一个10进制数56,将56加65(即把56从右向左读),得到121是一个回文数。

又如:对于10进制数87:
STEP1:87+78 = 165 STEP2:165+561 = 726
STEP3:726+627 = 1353 STEP4:1353+3531 = 4884
在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884。

写一个程序,给定一个N(2<=N<=10或N=16)进制数M,其中16进制数字为0-9与A-F,求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”

格式

输入格式

共两行
第一行为进制数N(2<=N<=10或N=16)
第二行为N进制数M(0<=M<=maxlongint)

输出格式

共一行
第一行为“STEP=”加上经过的步数或“Impossible!”

样例1

样例输入1

9
87

样例输出1

STEP=6

限制

各个测试点1s

来源

NOIP1999提高组第2题



问题链接Vijos P1304 回文数

问题分析

这个问题是进位有关的问题,给的数进位不定,不能按照10进制进行处理,如何存储数是关键。

阿拉伯记数法中,高位在左边,低位在右边。

程序读入数据时,是从左到右的。

数存储在数组中,低位从下标0开始存放,高位放在下标大的元素单元中,计算处理比较方便。

程序说明

数组v[]用于存储数,每个元素存放1位,低位从下标0开始存放,高位放在下标大的元素单元中。

数组rv[]用于存储逆序的数。

变量len的值是数的位数。

程序中的各个函数功能,参见源程序。

题记

写程序就要写简洁的程序。

采用合适的数据表示,可以大幅简化程序逻辑。


参考链接:(略)


AC的C++程序如下:

#include <iostream>
#include <string>

using namespace std;

const int N = 30;
const int N2 = 20;

char v[N2], rv[N2], len;

// 函数功能:判断n是否为回文数
bool isPalindrome(int len, char v[])
{
    int start = 0, end = len - 1;

    while(start < end) {
        if(v[start] != v[end])
            return false;

        start++, end--;
    }

    return true;
}

// 将字符串转换为整数:按位存储到数组,低位从下标0开始存放,高位放在大下标的单元
inline int myatoi(string& s, char v[])
{
    int len = s.length();
    for(int i=len-1,j=0; i>=0; i--,j++)
        if(s[i] >= 'A')
            v[j] = s[i] - 'A' + 10;
        else
            v[j] = s[i] - '0';

    return len;
}

// 将数组v[]中的数,逆序放到数组rv[]中
inline void setRight(int len, char v[], char rv[])
{
    for(int i=0; i<len; i++)
        rv[len - 1 - i] = v[i];
}

// 两数相加
inline int add(int len, char v[], char rv[], char base)
{
    int carry = 0;
    for(int i=0; i<len; i++) {
        v[i] += rv[i] + carry;
        carry = v[i] / base;
        v[i] %= base;
    }
    if(carry > 0)
        v[len++] = carry;

    return len;
}

int main()
{
    int n, i;
    string m;

    cin >> n >> m;

    len = myatoi(m, v);
    for(i=1; i<=N; i++) {
        setRight(len, v, rv);
        len = add(len, v, rv, n);

        if(isPalindrome(len, v))
            break;
    }

    if(i <= N)
        cout << "STEP=" << i << endl;
    else
        cout << "Impossible!" << endl;

    return 0;
}




原文地址:https://www.cnblogs.com/tigerisland/p/7563830.html