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 }
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
原文地址:https://www.cnblogs.com/Blogggggg/p/7397133.html