题目详情
Njzy在对回文数的学习过程中发现了一个有趣的问题.
这个问题是求一个数的回文距离。一个数的回文距离的定义是它减去一个回文数的绝对值的最小值。
比如:121的回文距离就是0,因为|121-121|=0,123的回文距离是2,|123-121|=2
输入描述:
输入包含多组测试数据,每组测试数据包含一个整数a,
(0<a<10^18)。
输出描述:
对于每组测试数据输出相应的答案。
答题说明
输入样例:
121
123
输出样例:
0
2
方法:构造靠近给定数据的回文数即可。
如107 构造 111 -----> 4,而构造101得到6并非最小
1229 构造 1221 -----> 8
9399 构造 9449 -----> 50,而构造9339得到60并非最小
1910 构造 1881 -----> 29,而构造1991得到71并非最小
可见只需将开头到(len-1)/2的数字提取出来形成一个新的数prevalue,作为回文数的前半部分构造回文数,与原数比较得到一个回文距离。
然后prevalue分别加一和减一,作为新的回文数的前半部分,总共计算得到三个回文距离,取最小的那个即可。
我提交的代码
#include <iostream>
#include <cstring>
using namespace std;
long long dist( long long value, int num[], int len)
{
if(len % 2 == 0)
{
int i = (len-1) / 2;
int j = i + 1;
for(;j < len && i >= 0; i--, j++)
{
num[j] = num[i];
}
}
else
{
int j = (len-1) / 2;
int i = j-1;
j = j+1;
for(;j < len && i >= 0; i--, j++)
{
num[j] = num[i];
}
}
long long pnum = 0;
long long ten = 1;
for( int i = len-1; i >= 0; i--)
{
pnum += num[i]*ten;
ten *= 10;
}
if(pnum > value)
return pnum - value;
else
return value - pnum;
}
long long palindromeDist( char str[])
{
int len = strlen(str);
int num[20];
long long value = 0;
for( int i = 0; i < len; i++)
num[i] = str[i] - '0';
long long ten = 1;
for( int i=len-1; i>=0; i--)
{
value += num[i]*ten;
ten *= 10;
}
long long ans = dist(value,num,len);
int mid = (len-1)/2;
long long prevalue = 0;
ten = 1;
for( int i=mid; i>=0; i--)
{
prevalue += num[i]*ten;
ten *= 10;
}
//inc 1
if(prevalue < ten-1)
{
long long tpv = prevalue;
tpv++;
int ind = mid;
while(tpv > 0)
{
num[ind--] = tpv%10;
tpv /= 10;
}
long long tpans = dist(value,num,len);
if(tpans < ans)
ans = tpans;
}
//dec 1
if(prevalue > ten/10)
{
long long tpv = prevalue;
tpv--;
int ind = mid;
while(tpv > 0)
{
num[ind--] = tpv%10;
tpv /= 10;
}
long long tpans = dist(value,num,len);
if(tpans < ans)
ans = tpans;
}
return ans;
}
int main( void)
{
char input[50];
while(cin>>input)
{
cout<<palindromeDist(input)<<endl;
}
return 0;
}
#include <cstring>
using namespace std;
long long dist( long long value, int num[], int len)
{
if(len % 2 == 0)
{
int i = (len-1) / 2;
int j = i + 1;
for(;j < len && i >= 0; i--, j++)
{
num[j] = num[i];
}
}
else
{
int j = (len-1) / 2;
int i = j-1;
j = j+1;
for(;j < len && i >= 0; i--, j++)
{
num[j] = num[i];
}
}
long long pnum = 0;
long long ten = 1;
for( int i = len-1; i >= 0; i--)
{
pnum += num[i]*ten;
ten *= 10;
}
if(pnum > value)
return pnum - value;
else
return value - pnum;
}
long long palindromeDist( char str[])
{
int len = strlen(str);
int num[20];
long long value = 0;
for( int i = 0; i < len; i++)
num[i] = str[i] - '0';
long long ten = 1;
for( int i=len-1; i>=0; i--)
{
value += num[i]*ten;
ten *= 10;
}
long long ans = dist(value,num,len);
int mid = (len-1)/2;
long long prevalue = 0;
ten = 1;
for( int i=mid; i>=0; i--)
{
prevalue += num[i]*ten;
ten *= 10;
}
//inc 1
if(prevalue < ten-1)
{
long long tpv = prevalue;
tpv++;
int ind = mid;
while(tpv > 0)
{
num[ind--] = tpv%10;
tpv /= 10;
}
long long tpans = dist(value,num,len);
if(tpans < ans)
ans = tpans;
}
//dec 1
if(prevalue > ten/10)
{
long long tpv = prevalue;
tpv--;
int ind = mid;
while(tpv > 0)
{
num[ind--] = tpv%10;
tpv /= 10;
}
long long tpans = dist(value,num,len);
if(tpans < ans)
ans = tpans;
}
return ans;
}
int main( void)
{
char input[50];
while(cin>>input)
{
cout<<palindromeDist(input)<<endl;
}
return 0;
}