zoukankan      html  css  js  c++  java
  • 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;
    }




  • 相关阅读:
    数组地址,数组首地址与数组首元素地址的区别
    memset,memcpy与strcpy
    OJ之大数与高精度题必备知识
    OJ之星期几算法(泽勒一致性)
    二分查找及其优化
    爱上vim之快捷键使用技巧与个性化配置
    shell之终极shell——zsh
    memset的一些坑
    OO终章
    hOmewOrk 第三单元 总结
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7563830.html
Copyright © 2011-2022 走看看