AtCoder Beginner Contest 229 D - Longest X
阿新 • • 發佈:2021-12-16
題意
給定一個只包含'X'和'.'的串和整數k,可以對串進行k次替換,每次把一個'.'替換成'X'。
串的長度和k的範圍都是2e5級別。
問:替換完成後,最多有多少個連續的'X'?
題解
公理1:最多替換k次。
公理2:複雜度支援遍歷串的所有'.',進行滑動視窗。
性質1:最終替換結果一定是"靠在"一個比較長的"X串"上。
性質2:每個'.'都有左邊和右邊的X數量,數量從0到|S|-1。
性質3:儘可能多地替換'.',答案才能最優。
答案1(公理2、性質3):要做一個滑動視窗,儘可能的統計答案。每次統計替換了'.'之後的'X'的連續數量。
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> using namespace std; const int MAXN = 3e5; char s[MAXN]; struct Point { int lastNum;//前面的'X'數量 int nextNum;//後面的'X'數量 }p[MAXN]; int cnt = 0;//點數量 int main() { scanf("%s", &s); int k; scanf("%d", &k); int len = strlen(s); int xCnt = 0;//X數量 int tmpAns = 0; for (int i = 0; i < len; i++) { if (s[i] == '.') { p[++cnt].lastNum = xCnt; tmpAns = max(tmpAns, xCnt); xCnt = 0; }else { xCnt++; } } int tmpCnt = cnt; xCnt=0; for (int i = len-1; i >=0; i--) { if (s[i] == '.') { p[tmpCnt].nextNum = xCnt; tmpAns = max(tmpAns, xCnt); tmpCnt--; xCnt = 0; } else { xCnt++; } } if (cnt<=k) { printf("%d\n",len); return 0; } if (k == 0) { //返回最大連續子段和 printf("%d\n", tmpAns); return 0; } //lastNum 前面的'X'數量 //nextNum 後面的'X'數量 int l=1,r; int totX=p[l].lastNum+1;//總共能夠覆蓋的X數量 int ans=totX; //第一次拓展 for(r = l+1; r <= l+k-1&&r<=cnt; r++) { totX++;//本身 totX+=p[r].lastNum; if(r==l+k-1){ totX+=p[r].nextNum; } ans=max(ans,totX); } r--; //邊緣拓展 拓展cnt-len次 for (int i = 1; i <= cnt-k; i++) { totX-=p[l].lastNum; l++; r++; totX+=p[r].nextNum; ans=max(ans,totX); } printf("%d\n",ans); return 0; }
TRANSLATE with x English TRANSLATE with EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: