noip1999 回文数 (模拟)

本文介绍了一个算法,用于解决给定N进制数M最少需要几步操作变为回文数的问题。通过数组存储数的每一位并实现逆序相加,判断结果是否为回文数,若30步内无法达成则输出特定信息。
A1121. 回文数
时间限制: 1.0s   内存限制: 256.0MB  
总提交次数: 702   AC次数: 214   平均分: 52.96
将本题分享到:
       
   
试题来源
  NOIP1999 提高组
问题描述
  若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
  例如:给定一个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与M
输出格式
  如果能在30步以内得到回文数,输出“STEP=xx”(不含引号),其中xx是步数;否则输出一行”Impossible!”(不含引号)
样例输入
9
87
样例输出
STEP=6

    解析:需要注意的是,读入的数可能为16进制数。在这里我采用的是用一个数组来存储数字m的每一位,这样每次相加时,只需要将数组的顺序与逆序相加就能得到新的数。

    代码:

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<cstdlib>
    #define maxn 100
    using namespace std;
    int n,a[2][maxn];
    char s[maxn];
    bool huiwen(int x)
    {
      int i,j,k;
      i=1,j=a[x][0];
      for(;i<j;i++,j--)
        if(a[x][i]!=a[x][j])return 0;
      return 1;  
    }
    void readdata()
    {
      int i,j,k;
      scanf("%d%s",&n,s);
      k=strlen(s);
      for(i=k-1;i>=0;i--)
        {
          if(isdigit(s[i]))j=s[i]-'0';
          if(islower(s[i]))j=s[i]-'a'+10;
          if(isupper(s[i]))j=s[i]-'A'+10;
          a[0][++a[0][0]]=j;
        }
      if(huiwen(0)){printf("STEP=0\n");exit(0);}  
    }
    void add(int x)
    {
      int i,j,k,last,y=1-x;
      a[x][0]=a[y][0];
      for(last=0,i=1;i<=a[y][0];i++)
        {
          j=a[y][0]+1-i;
          a[x][i]=a[y][i]+a[y][j]+last;
          last=a[x][i]/n,a[x][i]%=n;
        }
      if(last>0)a[x][++a[x][0]]=last;  
    }
    int main()
    {
      readdata();
      for(int i=1;i<=30;i++)
        {
          add(i%2);
          if(huiwen(i%2)){printf("STEP=%d\n",i);return 0;}
        }
      printf("Impossible!\n"); 
      return 0;
    }


      评论 3
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

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

      抵扣说明:

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

      余额充值