您的位置:首页 > 其它

PAT 1079. 延迟的回文数 (20)

2018-02-27 11:37 323 查看
题目描述:
给定一个 k+1 位的正整数 N,写成 ak...a1a0 的形式,其中对所有 i 有 0 <= ai < 10 且 ak > 0。N 被称为一个回文数,当且仅当对所有 i 有 ai = ak-i。零也被定义为一个回文数。非回文数也可以通过一系列操作变出回文数。首先将该数字逆转,再将逆转数与该数相加,如果和还不是一个回文数,就重复这个逆转再相加的操作,直到一个回文数出现。如果一个非回文数可以变出回文数,就称这个数为延迟的回文数。(定义翻译自 https://en.wikipedia.org/wiki/Palindromic_number)给定任意一个正整数,本题要求你找到其变出的那个回文数。输入格式:输入在一行中给出一个不超过1000位的正整数。输出格式:对给定的整数,一行一行输出其变出回文数的过程。每行格式如下A + B = C
其中A是原始的数字,B是A的逆转数,C是它们的和。A从输入的整数开始。重复操作直到C在10步以内变成回文数,这时在一行中输出“C is a palindromic number.”;或者如果10步都没能得到回文数,最后就在一行中输出“Not found in 10 iterations.”。
输入样例 1:
97152
输出样例 1:
97152 + 25179 = 122331
122331 + 133221 = 255552
255552 is a palindromic number.
输入样例 2:
196
输出样例 2:
196 + 691 = 887
887 + 788 = 1675
1675 + 5761 = 7436
7436 + 6347 = 13783
13783 + 38731 = 52514
52514 + 41525 = 94039
94039 + 93049 = 187088
187088 + 880781 = 1067869
1067869 + 9687601 = 10755470
10755470 + 07455701 = 18211171
Not found in 10 iterations.
题目分析:本题目实则就是在考查大整数的加法运算。笔者设置了bignumber结构体存储大整数的每一位以及位数。因为不知道读入大整数的位数,所以需要先使用字符数组进行存储,之后设置change函数转化成bignumber。另外需要设置逆转函数reverse,求和函数add,判断是不是回文数的函数judge,以及将一个大整数复制到另外一个大整数中存储的copy函数。
注意点:本题目没有说明最先输出的a是不是回文数,所以一定要对其进行判断,是回文数的话直接按照格式输出,不许进行下面的计算。本题目有三个测试点的陷阱在这里。
代码如下:#include<stdio.h>
#include<string.h>
const int maxn=1010;
struct bign{ //大整数结构体。
int num[maxn],len; //将大整数的每一位上的数字分别存放到数组num[]中。len存储大整数的位数
bign(){
num[maxn]={0}; //初始化
len=0;
}
}bignA,bignB,bignC; //按照题目要求定义三个大整数
bign change(char arr[]){ //读入的字符数组转化到大整数类型中进行存储,需注意的是:要将大整数的高位存储到结构体成员整型数组的高位置
bign ans;
for(int i=strlen(arr)-1;i>=0;i--){ //从低位开始转化
ans.num[ans.len++]=arr[i]-'0';
}
return ans; //最后返回答案。
}
bool judge(bign big){ //判断是不是回文数
for(int i=0,j=big.len -1;j>=0;i++,j--){
if(big.num[i]!=big.num[j]){ //对每一位进行核对
return false; //有一位不满足,则不是回文数,返回false
}
}
return true; //是回文数 返回true
}
bign add(bign f1,bign f2){ //将两个大整数进行求和 ,结果存放在ans中
bign ans;int carry=0; //carry为进位
for(int i=0;i<f1.len||i<f2.len;i++){ //以位数更大的作为跳出循环条件,其实此题目不必要,因为两个大整数的位数一样
int temp=carry+f1.num[i]+f2.num[i]; //请类比加法的计算过程,当前位置的相加结果=上一次相加产生的进位+两个整数本位数字之和
ans.num[ans.len++]=temp % 10; //对10去余,余数为ans中的该位上的数字
carry=temp/10; //商作为进位参加一下位的计算
}
if(carry!=0){ //如果到最后进位不为零,直接赋给结果ans的最高为
ans.num[ans.len++]=carry;
}
return ans; //返回求和结果
}
bign reverse(bign f1
4000
){ //逆转函数
bign ans;
for(int i=f1.len -1;i>=0 ;i--){
ans.num[ans.len++]=f1.num[i];
}
return ans;
}
void print(bign f1){ //输出大整数的函数print
for(int i=f1.len-1;i>=0;i--){
printf("%d",f1.num[i]);
}
}
bign copy(bign f1){ //讲一个大整数复制给另外一个大整数的copy函数
bign ans;
for(int i=0;i<f1.len;i++){
ans.num[ans.len++]=f1.num[i];
}
return ans;
}
int main()
{
int step=10; //步数
char str[maxn];
scanf("%s",str); //以字符读入该数
bignA=change(str); //将其转化成大整数存放在bignA
while(step--){
if(judge(bignA)){
print(bignA);printf(" is a palindromic number.");break; //如果初始数bignA 就是回文数,那么直接跳出循环按照格式输出即可,该步骤也可以放在循环外面
}
bignB=reverse(bignA); //逆转数
bignC=add(bignA,bignB); //求和
print(bignA);printf(" + ");print(bignB);printf(" = ");print(bignC); //按照格式输出
printf("\n");
if(judge(bignC)){
print(bignC);printf(" is a palindromic number.");break; //如果计算过程中某一次的和是回文数,则输出,跳出循环
}
else {
bignA=copy(bignC); //不是回文数,将该数复制给bignA 进行循环
}

}
if(step==-1){
printf("Not found in 10 iterations."); //十步运行结束,还不是回文数,则按照格式输出
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  PAT