题目连接在此。
一道大整数加法+简单模拟题。
大整数运算相关内容,请看这里。
题意
定义一种操作:让一个整数加上这个整数转置后的数。(例如123,转置后为321,两数相加123+321=444)
现在给出一个整数以及限制的操作次数,问在限定次数内是否能够得到回文数(上例中的444就是回文数)。如果在限定次数内能得到,输出这个回文数,并输出操作次数;如果在限定的操作次数内不能得到回文数,则输出最后一次操作得到的数字,以及操作次数。(定义一位数为回文数)
思路
我们需要以下几个操作:
1. 大数加法
2. 大数转置
3. 判断一个数是否是回文数
实现了以上函数之后只需对题目所诉操作进行模拟即可。
AC代码
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
struct bign{ //big number
int num[100];
int len;
bign(){
memset(num, 0, sizeof(num));
len = 0;
}
};
void print(bign a);
void charToInt(char temp[], bign &n){ //将char[]型temp转换成int型
for(int i = 0; i < n.len; i++){
n.num[n.len-i-1] = temp[i]-'0';
}
}
bool isPalindromic(bign n){ //判断n是不是回文数
int i = 0, j = n.len-1;
for(i,j; i <= j; i++,j--){
if(n.num[i] != n.num[j]) return false; //不是回文数
}
return true; //是回文数
}
bign reverse(bign n){ //反转一个数
bign temp;
temp.len = n.len;
for(int i = 0; i < n.len; i++){
temp.num[i] = n.num[n.len-1-i];
}
return temp;
}
bign add(bign a, bign b){ //两个大整数相加求和
bign res;
int carry = 0;
for(int i = 0; i<a.len || i<b.len; i++){
carry = carry+a.num[i]+b.num[i];
res.num[i] = carry%10;
carry /=10 ;
res.len++;
}
res.num[res.len++] = carry;
//去除前导零
while(res.len-1 >= 1 && res.num[res.len-1] == 0){
res.len--;
}
return res;
}
void print(bign a){
for(int i = a.len-1; i >= 0; i--){
printf("%d",a.num[i]);
}
printf("\n");
}
int main(){
bign n;
int k;
char temp[15];
while(scanf("%c",&temp[n.len])){ //读入n
if(temp[n.len] == ' ') break;
n.len++;
}
scanf("%d",&k); //读入K
charToInt(temp,n); //将temp转换成int放入n
int count = 0; //记录操作次数
do{ //进行题目所述操作
if(isPalindromic(n)){ // 如果n是回文数
print(n);
printf("%d\n",count); //输出操作次数
return 0;
}else{ //如果n不是回文数,则进行题设操作
bign newN = reverse(n); //反转n
n = add(n, newN);
}
count++;
}while(count < k);
print(n);
printf("%d\n",k);
return 0;
}