2018 ACM-ICPC北京賽區 Palindromes 【迴文數】
時間限制:1000ms
單點時限:1000ms
記憶體限制:512MB
描述
Recently, Nvoenewr learnt palindromes in his class.
A palindrome is a nonnegative integer that is the same when read from left to right and when read from right to left. For example, 0, 1, 2, 11, 99, 232, 666, 998244353353442899 are palindromes, while 10, 23, 233, 1314 are not palindromes.
Now, given a number, Nvoenewr can determine whether it's a palindrome or not by using loops which his teacher has told him on the class. But he is now interested in another question: What's the K-th palindrome? It seems that this question is too difficult for him, so now he asks you for help.
Nvoenewr counts the number from small to big, like this: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101 and so on. So the first palindrome is 0 and the eleventh palindrome is 11 itself.
Nvoenewr may ask you several questions, and the K may be very big.
輸入
The first line contains one integer T(T <= 20) —— the number of questions that Nvoenewr will ask you.
Each of the next T lines contains one integer K. You should find the K-th palindrome for Nvoenewr.
Let's say K is a n-digit number. It's guaranteed that K >= 1, 1 <= n <= 100000 and the sum of n in all T questions is not greater than 1000000.
輸出
Print T lines. The i-th line contains your answer of Nvoenewr's i-th question.
樣例輸入
4
1
10
11
20
樣例輸出
0
9
11
101
題目大意:輸出第K個迴文數字,K的長度範圍是1e5。
解題思路:我們很容易看出來,長度為1的迴文數的個數是10,長度為2的迴文數的個數是9,長度為3的迴文串的個數是90,長度為4的迴文串的個數是90,以此類推,後面依次是900,900,9000,9000,90000,90000……找到這個規律以後我們就能算出第k個迴文數字是長度為n的迴文數的第m個,迴文數是對稱的,所以我們只需要輸出前一半,然後後一半逆序輸出就好了,而長度為n的第m個的前一半是m+99…((n-1)/2個9 ),輸出迴文數的前一半,若n為偶數,逆序輸出前一半,若n為奇數,除去最後一位以外逆序輸出前一半,n為1的時候特殊處理直接輸出m-1就行。
可是我們發現K的長度範圍是1e5,注意是長度範圍而不是資料範圍,所以按上面的方法計算是非常不現實的。其實這道題的正確開啟方式是找規律,按字串來處理,分為以下幾種情況:(可以輸出前1e9個打表找規律)
1. 字串長度為1的時候直接輸出s[0]-1;
2. 字串長度為2且s[0]=1,s[1]=0的時候直接輸出9;
3. s[0]=1且s[1]=0的時候
4. s[0]=1且s[1]!=0的時候
5. s[0]!=1的時候
AC程式碼:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int T;
char s[100100];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%s",s);
int len=strlen(s);
if(len==1)//字串長度為1的時候直接輸出s[0]-1
{
printf("%c\n",s[0]-1);
continue;
}
if(len==2&&s[0]=='1'&&s[1]=='0')//字串長度為2且s[0]=1,s[1]=0的時候直接輸出9
{
printf("9\n");
continue;
}
if(s[0]=='1')
{
if(s[1]=='0')//s[0]=1且s[1]=0的時候
{
printf("9");
for(int i=2;i<len;i++)
printf("%c",s[i]);
for(int i=len-2;i>1;i--)
printf("%c",s[i]);
printf("9\n");
}
else//s[0]=1且s[1]!=0的時候
{
for(int i=1;i<len;i++)
printf("%c",s[i]);
for(int i=len-1;i>0;i--)
printf("%c",s[i]);
printf("\n");
}
}
else//s[0]!=1的時候
{
printf("%c",s[0]-1);
for(int i=1;i<len;i++)
printf("%c",s[i]);
for(int i=len-2;i>0;i--)
printf("%c",s[i]);
printf("%c\n",s[0]-1);
}
}
return 0;
}