回文数

来源:互联网 发布:sql update嵌套select 编辑:程序博客网 时间:2024/04/30 20:24

FJNU.1461

Description
若一个数(首位不为零)从左向右读与从右向左读都是一样,我们就将其称之为回文数。例如:给定一个 10进制数 56,将 56加 65(即把56从右向左读),得到 121是一个回文数。又如,对于10进制数87, 
                  STEPl: 87+78= 165       STEP2: 165+561= 726
                  STEP3: 726+627=1353      STEP4:1353+3531=4884
在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884。
写一个程序,给定一个N(2<N<=16)进制数 M.求最少经过几步可以得到文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible”

Input
输入N M

Output
在第几STEP可以得到回文数

Sample Input
9 87

Sample Output
6

Source
NOIP

My Program

#include<stdio.h>
#include
<string.h>
#define N 200

int pand(char s[])
{
    
int k=0,i,j,n=strlen(s);
    
while(s[k]=='0') k++;
    
for(i=k,j=n-1;i<j;i++,j--)
        
if(s[i]!=s[j])
            
return 0;
    
return 1;
}


void add(char a[],char b[],int n,int m)
{
    
int i;
    
for(i=m-1;i>0;i--)
    
{
        a[i]
+=b[i]-'0';
        
if(a[i]>='0'+n)
        
{
            a[i]
-=n;
            a[i
-1]++;
        }

    }

}


int main()
{
    
char a[N],b[N];
    
int m,n,k,i,s=0;
    scanf(
"%d%s",&n,a);
    
while(s<=30)
    
{
        
if(pand(a))
            
break;
        s
++;
        m
=strlen(a);
        i
=k=0;
        
while(a[k]=='0') k++;
        
for(i=m-k;i>k;i--)
            
if(a[i+k-1]>='A'&&a[i+k-1]<='F')
                a[i]
=a[i+k-1]-'A'+'9'+1;
            
else
                a[i]
=a[i+k-1];
        a[
0]='0';a[m-k+1]='/0';
        
for(i=1;i<=m-k;i++)
            b[i]
=a[m-k-i+1];
        b[
0]='0';b[i]='/0';
        add(a,b,n,i);
    }

    
if(s>30)
        printf(
"Impossible ");
    
else
        printf(
"%d ",s);
    
return 0;
}

 

YOYO's Note:
┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄它是华丽的分隔线

【题意简述】

将N进制的数M,与其倒置数在N进制下相加,判断要加几步才会变成一个回文数。


【粗略分析】

可能有高精度,因为涉及到进制转换,也可以算上字符串处理。
我的方法是,先读入数,{判断是否为回文,生成它的倒置数,N进制相加},repeat{}直到步数大于30……

【C源代码】

#include<stdio.h>
#include
<string.h>
#define N 200

int pand(char s[])
{
    
int k=0,i,j,n=strlen(s);
    
while(s[k]=='0') k++;
    
for(i=k,j=n-1;i<j;i++,j--)
        
if(s[i]!=s[j])
            
return 0;
    
return 1;
}


void add(char a[],char b[],int n,int m)
{
    
int i;
    
for(i=m-1;i>0;i--)
    
{
        a[i]
+=b[i]-'0';
        
if(a[i]>='0'+n)
        
{
            a[i]
-=n;
            a[i
-1]++;
        }

    }

}


int main()
{
    
char a[N],b[N];
    
int m,n,k,i,s=0;
    scanf(
"%d%s",&n,a);
    
while(s<=30)
    
{
        
if(pand(a))
            
break;
        s
++;
        m
=strlen(a);
        i
=k=0;
        
while(a[k]=='0') k++;
        
for(i=m-k;i>k;i--)
            
if(a[i+k-1]>='A'&&a[i+k-1]<='F')
                a[i]
=a[i+k-1]-'A'+'9'+1;
            
else
                a[i]
=a[i+k-1];
        a[
0]='0';a[m-k+1]='/0';
        
for(i=1;i<=m-k;i++)
            b[i]
=a[m-k-i+1];
        b[
0]='0';b[i]='/0';
        add(a,b,n,i);
    }

    
if(s>30)
        printf(
"Impossible ");
    
else
        printf(
"%d ",s);
    
return 0;
}

【注意事项】

※ 大数据量用scanf/printf可节约些时间~不过不用也不会TLE~..
※ 10进制以上数的处理~


【点评】

有点烦 = = 在对循环变量的几个控制点还不那么熟练……看来要多加练习了……

原创粉丝点击