题目大意:
给出k,让求出第k个回文数(k的“长度”不超过1e5)
题解:
真是一道给人警醒的题目
谁说数据范围大就要用Java!还有可能是找规律!
队友写java,构造,写了四个小时。
如果我也去一起看I题,如果我能质疑一下他们的思路,自己找规律看一下。。。。。。诶
打表仔细耐心看一下是可以发现规律的
①对于个位数和10,11就特判一下
②然后对于首个数字不是1的k,它对应的回文串就是将首数字减一,在反转顺序贴到后面
如k=523,则它对应的回文串就是42324
(注意,这种情况下,一定是将0-len-1位反转贴到后面,即中间要留一个)
③对于首个数字是1的k,是将它的首数字1直接抛弃,选取第2-len位
如果第2位数字不是0,就是将2-len位反转后贴到后面
如果第2位数字是0,先将0替换成9,再将2~len-1位反转后贴到后面(即这时中间要留一个)
#include <bits/stdc++.h>
#include <cstring>
#include<string>
using namespace std;
#define ll long long
int main()
{
int T,len;
string s,t,tt;
cin>>T;
while(T--)
{
cin>>s;
len=s.length();
if(len==1 || s=="11" || s=="10")
{
if(s=="11")
puts("11");
else if(s=="10")
puts("9");
else
cout<<(char)(s[0]-1)<<endl;
continue;
}
if(s[0]=='1')
{
if(s[1]=='0')
{
s[1]='9';
s=s.substr(1,len-1);
t=s.substr(0,len-2);
reverse(t.begin(),t.end());
s+=t;
cout<<s<<endl;
}
else
{
s=s.substr(1,len-1);
t=s;
reverse(t.begin(),t.end());
s+=t;
cout<<s<<endl;
}
continue;
}
s[0]-=1;
t=s.substr(0,len-1);
reverse(t.begin(),t.end());
s+=t;
cout<<s<<endl;
}
return 0;
}
打表程序
#include <bits/stdc++.h>
#include <cstring>
#include<string>
#include<cstdio>
#include<cstdlib>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
#define ll long long
bool pd(ll x)
{
ostringstream oss;
oss<<x;
string s=oss.str();
int len=s.length();
for(int i=0; i<len/2; ++i)
if(s[i]!=s[len-i-1])
return 0;
return 1;
}
int main()
{
//freopen("output.txt","w",stdout);
ll cnt=0;
for(ll i=0; i<=100000000000000000; ++i)
if(pd(i))
cout<<i<<"------"<<++cnt<<endl;
return 0;
}