问题描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个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
样例输出
tips:在对数组进行处理,尤其是进行加法运算的时候,注意一下这里数据的特殊性——回文数,这就意味着数组从低位到高位元素分别为167或者761都是一样的。意识到这一点,就给我们计算带来了很大方便,不需要去考虑什么低位的数字权重高什么的。。。
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个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
解析:回文数我们应该都可以懂是什么意思。理一下解题思路:判断是不是回文数->如果是,输出第一步;如果不是,按照题目要求进行加法,同时记录步数->每做一步,进行一次判断看是不是回文数,直到找到或者不可能为止。
理清了思路之后,我们就比较好写代码了:
#include<iostream>
#include<string.h>
using namespace std;
char a[100];
int b[100]={0};
int result[102]={0};
int sum = 0;
void trans_num(char judge[])//将字符型转化成数字型
{
for(int i = 0; i < sum; i++)
{
if(judge[i]>='a'&&judge[i]<='z')
b[i] = judge[i]-'a'+10;
else if(judge[i]>='A'&&judge[i]<='Z')
b[i] = judge[i]-'A'+10;
else
b[i] = judge[i]-'0';
}
}
void add(int judge[],int n)//实行加法运算 ,n表示n进制
{
result[0] = 0;//手动初始化
for(int i = 0; i < sum; i++)
{
result[i] += judge[i] + judge[sum-1-i];
result[i+1] = result[i]/n;//进位
result[i] = result[i]%n;//本位
}
if(result[sum]!=0)//产生进位
{
sum = sum + 1;
}
}
void trans_result_to_b(int judge[])//将add结果放入到b数组中
{
int j = 0;
for(int i = sum-1; i >= 0; i--)
{
b[j] = judge[i];
j++;
}
}
bool isPalindrome(int judge[])
{
int flag = 1;
int i = 0;
int j = sum-1;
while(1)
{
if(judge[i]!=judge[j])
{
flag = 0;
break;
}
else
{
if(i==j || i+1==j) break;
i++;
j--;
}
}
if(flag==0) return false;
else return true;
}
int main()
{
int N; //N进制
int step = 1;//记录步数
int flag = 0;//记录是否能找到回文数
cin>>N;
getchar();//吃回车
gets(a);//获得数组
sum = strlen(a);//数组的长度
trans_num(a);//将字符型数组转化成数字型数组
add(b,N);//进行加法运算
trans_result_to_b(result);//将结果数组放到b数组中
if(isPalindrome(b))
{
cout<<"STEP=0"<<endl;
}
else
{
while(1)
{
if(isPalindrome(b))
{
flag = 1;//找到回文数
break;
}
else if(step>30)
{
flag = 0;//没有找到回文数
break;
}
else
{
add(b,N);//进行加法运算
trans_result_to_b(result);//将结果数组放到b数组中
step++;
}
}
if(flag==1)
cout<<"STEP="<<step<<endl;
else
cout<<"Impossible!"<<endl;
}
return 0;
}
tips:在对数组进行处理,尤其是进行加法运算的时候,注意一下这里数据的特殊性——回文数,这就意味着数组从低位到高位元素分别为167或者761都是一样的。意识到这一点,就给我们计算带来了很大方便,不需要去考虑什么低位的数字权重高什么的。。。
最初的时候,进行进制转化时,我没有考虑到十六进制字母的转化,所以没有一次过,看来思维严密性还是有待提高。加油!
来源:CSDN
作者:allein_STR
链接:https://blog.csdn.net/allein_STR/article/details/77980005