题目介绍
A number that will be the same when it is written forwards or backwards is known as a Palindromic Number. For example, 1234321 is a palindromic number. All single digit numbers are palindromic numbers.
Non-palindromic numbers can be paired with palindromic ones via a series of operations. First, the non-palindromic number is reversed and the result is added to the original number. If the result is not a palindromic number, this is repeated until it gives a palindromic number. For example, if we start from 67, we can obtain a palindromic number in 2 steps: 67 + 76 = 143, and 143 + 341 = 484.
Given any positive integer N, you are supposed to find its paired palindromic number and the number of steps taken to find it.
Input Specification:
Each input file contains one test case. Each case consists of two positive numbers N and K, where N (≤1010) is the initial numer and K (≤100) is the maximum number of steps. The numbers are separated by a space.
Output Specification:
For each test case, output two numbers, one in each line. The first number is the paired palindromic number of N, and the second number is the number of steps taken to find the palindromic number. If the palindromic number is not found after K steps, just output the number obtained at the Kth step and K instead.
Sample Input 1:
67 3
Sample Output 1:
484
2
Sample Input 2:
69 3
Sample Output 2:
1353
3
注解
- 本来还想碰一碰,但估计没法头铁下去了。昨天刷1023就是想看看Long Long能不能混过去,结果最后用的【高精度乘法】,这次又想偷鸡,结果又卡在了【高精度加法】。
所以这就给考PAT提供了一些做题经验,如果发现题目有可能,到底是先偷鸡看一看,还是直接推复杂操作。至少在字符串处理这方面,我不想再头铁了,感觉可能会溢出,那就大概率会溢出。
- 本题给我带来了一种思路的打破。
以往我一想到要使用“高精度”的方法,第一时间想到的就是麻烦,因为要开int数组,原本属于string类型的一些方便的东西就都不能用了。(我当时学习高精度的文档,全是用int数组操作的,思路先入为主了)
结果到了这里才发现,原来string也能表现出很多数组的特性,我还一直以为它是一个很模板化的整体的东西。
在本次代码中,基本就将string当作char[ ]来使用了。
在每个位置进行加法时,结果的int值,是可以直接加到原本的字符上的。
因为在C中我们便学过,单个字符按照ASCII码是可以和整数直接对应的,在写程序时也常常会隐含这种字符的变化。比如:char m = 48 //'0'
而一个字符占据8位,2^8 = 256,我是不太清楚string里面这个是-128~127还是0~255,但是为了高精度加法使用是绝对够用了,不会有超出的可能的(因为一位一位的嘛)。
代码
最开始的18分代码(卡了两个Long Long溢出的点)
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long N,K;
cin>>N>>K;
//准备好两个要相加的字符串
string s1,s2;
s1 = to_string(N);
s2 = to_string(N);
reverse(s2.begin(),s2.end());
if(s1==s2) //初始就是回文数
{
cout<<s1<<endl;
cout<<0<<endl;
return 0;
}
int step=0;
while(K--)
{
step++;
//计算和
N = 0;
long long base = 1;
for(int i=s1.size()-1;i>=0;i--)
{
int sum = (s1[i]-'0')+(s2[i]-'0'); //计算当前位和(有可能进位)
N += base*(sum%10) + base*10*(sum/10);
base *= 10;
}
//重复进行
s1 = to_string(N);
s2 = to_string(N);
reverse(s2.begin(),s2.end());
if(s1==s2) break;
}
cout<<N<<endl;
cout<<step<<endl;
return 0;
}
使用了【高精度加法】思路的代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s1;
int K;
cin>>s1>>K;
//初始判断
string s2=s1;
reverse(s2.begin(),s2.end());
if(s1==s2)
{
cout<<s1<<endl;
cout<<0<<endl;
return 0;
}
int step=0;
int sum=0;
while(K--)
{
step++;
//进行高精度加法
int flag = 0; //有没有最后多出的一位
for(int i=s1.size()-1;i>=0;i--)
{
sum = s1[i]-'0'+s2[i]-'0';
s1[i] = sum%10 + '0';
if(i==0&&sum/10!=0)
{
flag=1;
break;
}
s1[i-1] += sum/10;
}
if(flag==1) s1 = to_string(sum/10)+s1;
s2 = s1;
reverse(s2.begin(),s2.end());
if(s1==s2) break;
}
cout<<s1<<endl;
cout<<step<<endl;
return 0;
}