标签:its 好的 tran float col bool hold 题意 数字
And where the are the phone numbers?
You are given a string s consisting of lowercase English letters and an integer k. Find the lexicographically smallest string t of length k, such that its set of letters is a subset of the set of letters of s and s is lexicographically smaller than t.
It‘s guaranteed that the answer exists.
Note that the set of letters is a set, not a multiset. For example, the set of letters of abadaba is {a,?b,?d}.
String p is lexicographically smaller than string q, if p is a prefix of q, is not equal to q or there exists i, such that pi?<?qi and for all j?<?i it is satisfied that pj?=?qj. For example, abc is lexicographically smaller than abcd , abd is lexicographically smaller than abec, afa is not lexicographically smaller than ab and a is not lexicographically smaller than a.
The first line of input contains two space separated integers n and k (1?≤?n,?k?≤?100?000) — the length of s and the required length of t.
The second line of input contains the string s consisting of n lowercase English letters.
Output the string t conforming to the requirements above.
It‘s guaranteed that the answer exists.
3 3
abc
aca
3 2
abc
ac
3 3
ayy
yaa
2 3
ba
baa
In the first example the list of strings t of length 3, such that the set of letters of t is a subset of letters of s is as follows: aaa, aab, aac, aba, abb, abc, aca, acb, .... Among them, those are lexicographically greater than abc: aca, acb, .... Out of those the lexicographically smallest is aca.
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1e5+10; char s[maxn]; bool vis[30]; int main() { int m,n; while(cin>>m>>n) { cin>>s; memset(vis,false,sizeof(vis)); for(int i=0; i<m; i++) vis[s[i]-‘a‘]=true; if(m<n) { for(int i=m; i<n; i++) { int f=1; for(int j=0; j<=26&&f; j++) { if(vis[j]) f=0,s[i]=j+‘a‘; } } } else { int f=0; for(int i=n-1; i>=0&&!f; i--) { int pos=s[i]-‘a‘; for(int j=pos+1; j<=26; j++) { if(vis[j]) { f=1; s[i]=j+‘a‘; break; } } if(!f) { int ff=1; for(int j=0; j<=26&&ff; j++) { if(vis[j]) ff=0,s[i]=j+‘a‘; } } } } for(int i=0;i<n;i++) cout<<s[i]; cout<<endl; } return 0; }
第一反应求g(x)时候,记忆化+打表。
然后看了下查询区间和查询次数的数据范围,打表时候还是把每个数对应的1--9的个数都求出来,每次查询时候直接一次O(1)的访问就差不多了。
#include<cstdio> #include<iostream> #include <cstring> #include <algorithm> #include <queue> #include<cmath> #define ll long long using namespace std; const int maxn=1e6+10; int a[maxn][10]; int num[maxn]; int get(int x) { if(num[x]!=-1) return num[x]; else if(x<=9) return x; else { int ans=1; while(x) { if(x%10!=0) ans*=(x%10); x/=10; } return get(ans); } } void pre() { memset(num,-1,sizeof(num)); for(int i=1;i<=maxn;i++) num[i]=get(i); //for(int i=20;i<=30;i++) printf("%d ",num[i]); for(int i=1;i<=9;i++) a[1][i]=0; a[1][1]=1; for(int i=2;i<=maxn;i++) { for(int j=1;j<=9;j++) { a[i][j]=a[i-1][j]; } int cnt=num[i]; a[i][cnt]++; } return ; } int main() { int n,x,l,r; pre(); while(~scanf("%d",&n)) { while(n--) { scanf("%d%d%d",&l,&r,&x); if(num[l]==x) cout<<a[r][x]-a[l][x]+1<<endl; else cout<<a[r][x]-a[l][x]<<endl; } } return 0; }
CodeForces - 940C + CodeForces - 932B (两道比较好的模拟题)
标签:its 好的 tran float col bool hold 题意 数字
原文地址:https://www.cnblogs.com/weimeiyuer/p/9087355.html