您的位置:首页 > 其它

Codeforces 946E - Largest Beautiful Number(贪心、构造)

2018-03-08 14:21 681 查看
E. Largest Beautiful Number

time limit per test1 second

memory limit per test256 megabytes

inputstandard input

outputstandard output

Yes, that’s another problem with definition of “beautiful” numbers.

Let’s call a positive integer x beautiful if its decimal representation without leading zeroes contains even number of digits, and there exists a permutation of this representation which is palindromic. For example, 4242 is a beautiful number, since it contains 4 digits, and there exists a palindromic permutation 2442.

Given a positive integer s, find the largest beautiful number which is less than s.

Input

The first line contains one integer t (1 ≤ t ≤ 105) — the number of testcases you have to solve.

Then t lines follow, each representing one testcase and containing one string which is the decimal representation of number s. It is guaranteed that this string has even length, contains no leading zeroes, and there exists at least one beautiful number less than s.

The sum of lengths of s over all testcases doesn’t exceed 2·105.

Output

For each testcase print one line containing the largest beautiful number which is less than s (it is guaranteed that the answer exists).

Example

inputCopy

4

89

88

1000

28923845

output

88

77

99

28923839

定义一个beautiful number就是长度为偶数,且数字重排后可以变成回文串,其实就是串内部所有的数字的出现次数都需要是偶数就对了。

现在给出一个字符串表示的数字s,让你找出比s小的最大的beautiful number。

为了让我们构造出来的结果尽量大而又不超过给定的s,当我们构造的串长度跟s相同时,就可以知道我们构造出来的串是前k-1位跟s对应位相同,第k位比s[k]小,然后后面k+1到n位能使串满足定义又尽量大。

所以我们从高位到低位枚举那个被修改小的位置k,然后从大到小枚举它被改成的数字,这样的复杂度是O(10*k),接下来如何判断成立与否了,因为前k-1位我们填的都是s串中对应的数,第k位又是我们枚举出来的,而我们又要满足所有数字出现次数为偶数次,所以前k位出现次数为奇数的数字都得在后面出现奇数次——所以,如果出现为奇数次的数字数量left大于n-k,则无法构造出来,否则可以。

至于构造方法,就是最后left位从大到小填上那些需要补全为偶数次的数字,中间剩余的位置都填9即可。

统计前k-1位每种数字出现的奇偶次数可以预处理出来,所以总复杂度是O(k)的。

若找不到满足的等长串,则输出n-2个9。

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=201015;
const int maxk=58500;
const int maxe=maxn*2;
const ll mod=1e9+7;
const int inf=0x3f3f3f3f;
int n,m;
char str[maxn];
int cou[maxn][10];
void func(){
for(int i=n;i>=1;i--){
for(int j=str[i]-'0'-1;j>=0;j--){
if(i==1&&j==0)continue;
int lef=0;
for(int k=0;k<10;k++){
lef+=cou[i-1][k]^(j==k);
}
if(lef<=n-i){
for(int k=1;k<i;k++){
putchar(str[k]);
}
putchar(j+'0');
for(int k=i+1;k<=n-lef;k++)putchar('9');
for(int k=9;k>=0;k--)if(cou[i-1][k]^(j==k))putchar(k+'0');
putchar('\n');
return;
}
}

}
for(int i=1;i<=n-2;i++)putchar('9');
putchar('\n');
return;
}

int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s",str+1);
n=strlen(str+1);
for(int i=1;i<=n;i++){
int idx=str[i]-'0';
for(int ii=0;ii<10;ii++)cou[i][ii]=cou[i-1][ii]^(ii==idx);
}
func();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: