题目传送门
1 /* 2 题意:任意排列第一个字符串,使得有最多的不覆盖a/b字符串出现 3 字符串处理/贪心:暴力找到最大能不覆盖的a字符串,然后在b字符串中动态得出最优解 4 恶心死我了,我最初想输出最多的a,再最多的b,然而并不能保证是最多的:( 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <string> 9 #include <iostream> 10 #include <algorithm> 11 #include <cmath> 12 using namespace std; 13 14 const int MAXN = 1e5 + 10; 15 const int INF = 0x3f3f3f3f; 16 char s[MAXN], a[MAXN], b[MAXN]; 17 int cnt_s[30], cnt_a[30], cnt_b[30]; 18 int len_s, len_a, len_b; 19 20 int main(void) //Codeforces Round #307 (Div. 2) B. ZgukistringZ 21 { 22 // freopen ("B.in", "r", stdin); 23 24 while (scanf ("%s", s) == 1) 25 { 26 scanf ("%s", a); scanf ("%s", b); 27 len_s = strlen (s); len_a = strlen (a); len_b = strlen (b); 28 29 memset (cnt_s, 0, sizeof (cnt_s)); 30 memset (cnt_a, 0, sizeof (cnt_a)); 31 memset (cnt_b, 0, sizeof (cnt_b)); 32 33 for (int i=0; i<len_s; ++i) cnt_s[s[i]-‘a‘]++; 34 for (int i=0; i<len_a; ++i) cnt_a[a[i]-‘a‘]++; 35 for (int i=0; i<len_b; ++i) cnt_b[b[i]-‘a‘]++; 36 37 int ans_a = 0, ans_b = 0; int tot = 100000; 38 for (int i=0; i<30; ++i) {if (cnt_a[i]) tot = min (tot, cnt_s[i] / cnt_a[i]);} 39 for (int i=0; i<=tot; ++i) 40 { 41 int p = 100000; 42 for (int j=0; j<30; ++j) {if (cnt_b[j]) p = min (p, (cnt_s[j] - i * cnt_a[j]) / cnt_b[j]);} 43 if (i + p > ans_a + ans_b) {ans_a = i; ans_b = p;} 44 } 45 46 for (int i=1; i<=ans_a; ++i) printf ("%s", a); 47 for (int j=1; j<=ans_b; ++j) printf ("%s", b); 48 for (int i=0; i<30; ++i) 49 { 50 for (int j=1; j<=cnt_s[i]-ans_a*cnt_a[i]-ans_b*cnt_b[i]; ++j) 51 printf ("%c", ‘a‘ + i); 52 } 53 puts (""); 54 } 55 56 return 0; 57 }
时间: 2024-09-30 18:14:52