1. 程式人生 > >Codeforces 794C【貪心】

Codeforces 794C【貪心】

一開始以為計數n*26的演算法很優秀哦?後面確實時間還是優秀的,只不過後面wa的自己程式碼就越來越浪,難看的…..;
對於1串只會取前(n+1)/2個字元,對於2串只會取n/2個字元(都是整除),然後每次拿1串的最小和2串的最大比一比,對於填1串,如果最小<最大,字典序越小,小的放最前,不放最前會被擠掉,如果最小>最大,字典序越小,大的放後面,然後2串的更大的放前面;對於填2串,如果最小<最大,字典序越大,大的放最前,不放最前會被擠掉,如果最小>最大,字典序越大,小的放後面,然後2串的更大的放前面

#include<iostream>
#include<cstdio>
#include<queue> #include<vector> #include<string.h> #include<algorithm> using namespace std; typedef long long LL; #define mem(a,b) memset(a, b, sizeof(a)) #define Lson num<<1,Left,Mid #define Rson num<<1|1, Mid+1, Right const int Maxn = 3e5 + 10; char s1[Maxn], s2[Maxn], ans[Maxn]; int
n, x, num, cnt1[30],cnt2[30], Left, Right, sum; int u, v; bool flag; bool Judge(){ for(int i=0;i<26;i++){ if(cnt1[i]){ u = i; break; } } for(int i=25;i>=0;i--){ if(cnt2[i]){ v = i; break; } } return
u < v; } int main(){ scanf("%s%s",s1,s2); n = strlen(s1); mem(cnt1, 0); mem(cnt2, 0); for(int i=0;i<n;i++){ x = s1[i] - 'a', cnt1[x]++; x = s2[i] - 'a', cnt2[x]++; } sum = 0; for(int i=0;i<26;i++){ if(sum + cnt1[i] >= (n+1)/2){ cnt1[i] = (n+1)/2 - sum; for(int j=i+1;j<26;j++) cnt1[j] = 0; break; } sum = sum + cnt1[i]; } sum = 0; for(int i=25;i>=0;i--){ if(sum + cnt2[i] > n/2){ cnt2[i] = n/2 - sum; for(int j=i-1;j>=0;j--) cnt2[j] = 0; break; } sum = sum + cnt2[i]; } num = 0; Left = 0, Right = n - 1; while(num < n){ if(Judge()){ for(int i=0;i<26;i++){ if(cnt1[i]){ u = i; cnt1[i]--; break; } } ans[Left++] = u + 'a'; num++; if(num == n) break; } else{ for(int i=25;i>=0;i--){ if(cnt1[i]){ v = i; cnt1[i]--; break; } } ans[Right--] = v + 'a'; num++; if(num == n) break; } if(Judge()){ for(int i=25;i>=0;i--){ if(cnt2[i]){ v = i; cnt2[i]--; break; } } ans[Left++] = v + 'a'; num++; if(num == n) break; } else{ for(int i=0;i<26;i++){ if(cnt2[i]){ u = i; cnt2[i]--; break; } } ans[Right--] = u + 'a'; num++; if(num == n) break; } } ans[num] = '\0'; printf("%s\n",ans); return 0; }