CF551B
题目链接:http://codeforces.com/contest/551/problem/B
题目大意:给出字符串a, b, c。试图合理的安排a的字母顺序,使其中有尽可能多的与 c 或 b 相同的不重叠的子串.。
解题思路:You just need some power! 记录 a, b, c 中各个字母的个数,然后枚举 b 能出现的所有次数,再算出 c 相应的能出现的次数,两者相加即为一个ans,最终答案即为ans最大的时候对应的情况。最坏情况下的时间复杂度:O(|a| * 26).
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cctype> 5 #include<cmath> 6 #include<cstdlib> 7 #include<cstring> 8 #include<functional> 9 #include<list> 10 #include<map> 11 #include<istream> 12 #include<ostream> 13 #include<queue> 14 #include<set> 15 #include<sstream> 16 #include<string> 17 #include<stack> 18 #include<string> 19 #include<vector> 20 using namespace std; 21 typedef long long ll; 22 typedef pair<int,int> P; 23 const int maxn=2000+5,inf=0x7ffffff; 24 int ca[30],cb[30],cc[30]; 25 int main(){ 26 string a,b,c; 27 cin>>a; 28 cin>>b; 29 cin>>c; 30 for(int i=0;i<a.size();i++) ca[a.at(i)-'a']++; 31 for(int i=0;i<b.size();i++) cb[b.at(i)-'a']++; 32 for(int i=0;i<c.size();i++) cc[c.at(i)-'a']++; 33 bool ending=false; 34 int ans=0; 35 P as; 36 for(int i=0;;i++){ 37 int ta=0; 38 int tempa[30]; 39 for(int j=0;j<26;j++) 40 tempa[j]=ca[j]; 41 for(int j=0;j<26;j++){ 42 if(tempa[j]<cb[j]*i){ 43 ending=true; 44 break; 45 } 46 tempa[j]-=(cb[j]*i); 47 } 48 if(ending) break; 49 ta+=i; 50 int ti=inf; 51 for(int j=0;j<26;j++){ 52 int ttt; 53 if(cc[j]>0){ 54 int ttt=tempa[j]/cc[j]; 55 ti=min(ti,ttt); 56 } 57 } 58 if(ti!=inf){ 59 ta+=ti; 60 } 61 if(ta>ans){ 62 ans=ta; 63 if(ti!=inf) 64 as=make_pair(i,ti); 65 else 66 as=make_pair(i,0); 67 } 68 } 69 int num_b=as.first,num_c=as.second; 70 for(int i=0;i<26;i++){ 71 ca[i]-=(cb[i]*num_b); 72 ca[i]-=(cc[i]*num_c); 73 } 74 string ret; 75 while(num_b>0){ 76 ret+=b; 77 num_b--; 78 } 79 while(num_c>0){ 80 ret+=c; 81 num_c--; 82 } 83 for(int i=0;i<26;i++){ 84 while(ca[i]>0){ 85 ret+=(i+'a'); 86 ca[i]--; 87 } 88 } 89 cout<<ret<<endl; 90 return 0; 91 }
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”