Codeforce 128B:String
题目链接:http://codeforces.com/problemset/problem/128/B
题目大意:给出一个字符串s,问字典序排第k个的子串是什么.
贪心
我们可以很轻松地求出以prefix为前缀的子串个数,故可以按字典序枚举后一个字母:
- 若以当前prefix+c('+'为字符串的连接操作)为前缀的子串个数和小于k,则继续枚举下一个前缀prefix+(c+1);
- 若以当前prefix+c为前缀的子串个数和小于等于k,那么所要求的子串的前缀定为prefix+c.
/*注意:子串和可能会爆int*/
代码如下:
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 using namespace std; 5 string s,ans; 6 int k,len; 7 void solve(vector<int> a,int &k){ 8 if(k<=0||(int)a.size()==0)return; 9 for(int j='a';j<='z';++j){ 10 long long pre=0; 11 for(int i=0;i<(int)a.size();++i) 12 if(s[a[i]]==j)pre+=len-a[i]; 13 if(pre>=k){ 14 ans+=j; 15 vector<int>t; 16 for(int i=0;i<(int)a.size();++i){ 17 if(s[a[i]]==j){ 18 k--; 19 if(a[i]+1<len)t.push_back(a[i]+1); 20 } 21 } 22 solve(t,k); 23 return; 24 }else k-=pre; 25 } 26 } 27 int main(void){ 28 std::ios::sync_with_stdio(false); 29 cin>>s>>k; 30 vector<int>a; 31 len=s.length(); 32 for(int i=0;i<len;++i)a.push_back(i); 33 solve(a,k); 34 if(k>0)cout<<"No such line."; 35 else cout<<ans; 36 }