日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AtCoder AGC036E ABC String

發(fā)布時間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AtCoder AGC036E ABC String 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接

https://atcoder.jp/contests/agc036/tasks/agc036_e

題解

看了題解第一句話之后意識到這題是sb題以及我又雙叒叕智障了……

首先去掉串中相鄰的相同字符,不妨設A,B,C出現(xiàn)次數(shù)依次遞增。用\(cnt\)來表示一個字符的出現(xiàn)次數(shù)。
\(cnt(B)=cnt(C)\), 那么可以刪去所有BC子串直至\(cnt(A)=cnt(B)=cnt(C)\),同時保證任何兩個A之間不能刪空。可以證明一定能做到,因為最壞情況刪完后是ABCABC...ABCA這樣。長度上界\(3\cdot cnt(A)\)可以達到。
\(cnt(B)<cnt(C)\), 首先我們盡量不改變A和B而去減少C. 考慮相鄰兩個A之間一定是B、C交替,有以下幾種類型:

(1) 開頭結尾都是B. 這種情況下我們什么都不能做。

(2) 開頭結尾一B一C. 這種情況下我們可以刪去開頭或結尾的C,把\(cnt(C)\)減少\(1\).

(3) 開頭結尾都是C. 如果這一段只有一個字符C且不在整個串的首尾, 我們什么都不能做,否則刪去首尾的C,把\(cnt(C)\)減少\(2\).
這樣做完后,有可能依然\(cnt(B)<cnt(C)\). 這時任何相鄰兩個A之間要么是C, 要么是BCBCBC...BCB.
我們的目標是把\(cnt(C)-cnt(B)\)縮小到\(0\), 刪后面那種顯然是不優(yōu)的,于是只能刪去\((cnt(C)-cnt(B))\)個AC. 這樣顯然是合法且最優(yōu)的。
時間復雜度\(O(n)\).

寫起來細節(jié)還挺多……

代碼

#include<bits/stdc++.h> #define llong long long #define mkpr make_pair #define riterator reverse_iterator using namespace std;inline int read() {int x = 0,f = 1; char ch = getchar();for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}return x*f; }const int N = 1e6; char a[N+3],b[N+3]; bool f[N+3]; char permu[3],permui[3]; int cnt[3],cnt2[3]; int n,n0;bool cmp_cnt(int x,int y) {return cnt[x]<cnt[y];}void reset() {n0 = 0; for(int i=1; i<=n; i++) {if(!f[i]) b[++n0] = a[i];}n = n0; for(int i=1; i<=n; i++) a[i] = b[i]; }int main() {scanf("%s",a+1); n = strlen(a+1);for(int i=1; i<=n; i++) a[i] -= 'A';memset(f,false,sizeof(f));for(int i=2; i<=n; i++) if(a[i]==a[i-1]) f[i] = true;reset();for(int i=1; i<=n; i++) cnt[a[i]]++;for(int i=0; i<3; i++) permu[i] = i;sort(permu,permu+3,cmp_cnt); sort(cnt,cnt+3);for(int i=0; i<3; i++) permui[permu[i]] = i;for(int i=1; i<=n; i++) a[i] = permui[a[i]];int dif = cnt[2]-cnt[1];memset(f,false,sizeof(f));for(int l=(a[1]==0?2:1); l<=n;){int r = l;while(r<n&&a[r+1]!=0) {r++;}if(dif>0&&!(l==r&&l>1&&r<n)&&!(a[l]==1&&a[r]==1)){if(a[l]==2&&dif>0) {f[l] = true; dif--;}if(r>l&&a[r]==2&&dif>0) {f[r] = true; dif--;}}l = r+2;}reset();if(dif>0){memset(f,false,sizeof(f));for(int l=(a[1]==0?2:1); l<=n;){int r = l;while(r<n&&a[r+1]!=0) {r++;}if(l==r&&a[l]==2&&l>1&&r<n&&dif>0) {f[l] = f[l-1] = true; dif--;}l = r+2;}reset();}memset(cnt,0,sizeof(cnt));for(int i=1; i<=n; i++) cnt[a[i]]++;dif = cnt[1]-cnt[0];memset(f,false,sizeof(f));for(int l=(a[1]==0?2:1); l<=n;){int r = l;while(r<n&&a[r+1]!=0) {r++;}int rst = r-l+1;for(int i=l+1; i<=r; i++){if(a[i]==2&&a[i-1]==1&&dif>0&&(l==1||r==n||rst>2)) {f[i] = f[i-1] = true; dif--; rst-=2;}}l = r+2;}reset();for(int i=1; i<=n; i++) printf("%c",permu[a[i]]+'A'); puts("");return 0; } 與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的AtCoder AGC036E ABC String的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。