标签:max amp main tin 技术 枚举 opened mes sign
题目链接:https://codeforces.com/contest/1493/problem/C
题意:给定字符串s 求一个字典序最小的字符串t 满足 t的字典序>=s 并且 其中出现的字母次数可以被k整除
思路:考虑枚举哪个位置变大, 再枚举变成哪一个字母
然后利用前缀和 找前面的有多少个需要填补的, 看后面的个数是否可以填补上, 因为当前这个字母改了
后面的字母可以任意修改,然后填完之后 空白的位置都填a 如果空白的位置数量不能被k整除也是不合法的
时间复杂度O(n*26*26)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 const int mod=1e9+7; 5 #define ll long long 6 #define ull unsigned long long 7 #define pi pair<int,ll> 8 #define fi first 9 #define sc second 10 #define pb push_back 11 char s[maxn]; 12 int pre[maxn][26]; 13 14 15 16 int main() 17 { 18 ios::sync_with_stdio(0); 19 cin.tie(0); 20 int t; 21 cin>>t; 22 while(t--) 23 { 24 int n,k; 25 cin>>n>>k; 26 cin>>(s+1); 27 if(n%k) 28 { 29 cout<<-1<<‘\n‘; 30 continue; 31 } 32 int f=0; 33 for(int i=1;i<=n;i++) 34 { 35 int x=s[i]-‘a‘; 36 for(int j=0;j<26;j++) 37 { 38 pre[i][j]=pre[i-1][j]; 39 if(x==j) pre[i][j]++; 40 } 41 } 42 for(int i=0;i<26;i++) if(pre[n][i]%k) f=1; 43 if(!f) 44 { 45 cout<<(s+1)<<‘\n‘; 46 continue; 47 } 48 f=0; 49 for(int i=n;i>=1;i--) 50 { 51 if(f) break; 52 for(int j=s[i]-‘a‘+1;j<26;j++) 53 { 54 int num=n-i; 55 int cnt=0; 56 for(int y=0;y<26;y++) 57 { 58 int sum=pre[i-1][y]+(y==j); 59 cnt+=(k-sum%k)%k; 60 } 61 if(num>=cnt&&(num-cnt)%k==0) 62 { 63 string ans; 64 for(int y=1;y<i;y++) 65 ans+=s[y]; 66 ans+=char(j+‘a‘); 67 68 int shu=num-cnt; 69 for(int y=0;y<shu;y++) ans+=‘a‘; 70 for(int y=0;y<26;y++) 71 { 72 int sum=pre[i-1][y]+(y==j); 73 int ci=(k-sum%k)%k; 74 for(int x=0;x<ci;x++) 75 ans+=char(‘a‘+y); 76 } 77 cout<<ans<<‘\n‘; 78 f=1; 79 break; 80 } 81 } 82 } 83 } 84 85 86 87 }
标签:max amp main tin 技术 枚举 opened mes sign
原文地址:https://www.cnblogs.com/winfor/p/14495072.html