關於字串 zero 的特殊解法

2021-08-15 08:55:15 字數 2464 閱讀 1710

字串(zero)

給你乙個只包含「0」與「1」的字串s,你可以對這個字串進行操作,每次操作將字串中任意乙個字元移動到字串的任意位置,例如s=「0010」』,你可以將首位的0移動到末尾位置,使得s=「0100」。

現在有q次詢問,每次詢問給出乙個操作次數上限k,每次詢問你需要回答在對字串s進行不超過k次操作後,字串最長連續「0」的長度。

輸入 第一行乙個01字串s

第二行乙個整數q,代表詢問次數

接下來q行,每行乙個數字ki

輸出 輸出q行,每行乙個整數,代表對應詢問中字串最長連續「0」的長度

樣例輸入

0000110000111110

5 1

2 3

4 5

樣例輸出

5 8

9 9

9 資料規模

對於30%的資料,n≤1,000,q≤1,000,字串長度為n

對於100%的資料,n≤1,000,000,n×q≤20,000,000, ki≤q

時限2s,空間256mb

首先分析題目,我們可以知道,題目的大概意思是對於k次移動操作在乙個字串上,可以得到連續的0多少個。

實際上,操作我們只需要分成兩類,一類是把1移走(移到字串的邊緣,相當於刪除了1),另一類是把0移入一串0中。

並且,由於它的詢問個數各不相同,形成的解也各不相關,所以動態規劃之類的做法並不容易,那麼我們就可以想到,如果在這個字串中,任意取一段區間[l,r],並且保證這裡面的1的個數≤k,那麼我們就可以肯定,區間[l,r]中形成的一串0的個數就是其本身0的個數+k次操作-其本身1的個數。

另一方面,我們可以肯定,為了保證取得值更大,無論是l還是r,都應當指向0處,而l和r乙個個移動很明顯會耗費不少時間。

所以我們可以大膽的建立乙個陣列x,對於這樣乙個陣列,我們肯定,一開始讀入的字串中,一開始的連續的1是毫無意義的。

所以,我們可以把初始的1刪去,保證一開始的讀入是0,並且最後的讀入中,讀入的1也可以刪去。

那麼我們就可以得到乙個x[n]的陣列,這個陣列中,我們記錄的是一串相同資料的大小。

x[1]是第一串0的個數,x[2]指第一串1的個數。用奇數偶數來區分0或者1。

然後同時建立乙個sum陣列,對於乙個值sum[i],表示從一開始到i時0或1的總個數,用奇數偶數來區分是0的個數還是1的個數。

然後我們可以列舉r的位置,因為我們保證r一定指向0的區間,所以每一次跳躍都可以使用+2的方式,l同理。

如果同時列舉l和r,空間複雜度必定大大增加,所以我們可以使用單調佇列的方式來優化l,解決題目。

如果不使用單調佇列,那麼我們就可以使用如下方法。

對於乙個初始也是唯一的區間[l,r],在r=r+2後,我們可以知道這乙個區間[l,r]的最優解可能還是[l,r],也可能是[r,r],所以我們只需要討論一次這種情況,詢問是否需要將l重新移動到r的位置就好了。

但是如果乙個區間[l,r]到一定的程度,其中的1的個數超過了我們所求的k,那麼就需要強制的將l向後移動,那麼由於沒有使用單調佇列,我們就需要重新掃一遍[l,r]區間中,求出其中的最優解。

當然,判斷它是否為最優解,我們只需要確定比較ans的值就好了。

因為ans=(k+[l,r]中0的個數-[l,r]中1的個數)

所以我們只需要比較,不同的ans的值並且對這個比較式進行化簡,就可以對當前的最優情況進行考慮了。

**如下:

#include 

using namespace std;

bool bo=true;

int x[1000000];

intsum[1000000];

int n=1,q;

int ans;

int l,r;

inline void readit()

c=getchar();

}return ;

}inline int read()

return x;

}int max(int ,int );

int min(int ,int );

int get0(int ,int );

int get1(int ,int );

int main()

if (bo)

for (int j=l+2;j2)

if (get0(l,r)-get1(l,r)-x[r]<=0)

l=r;

ans=max(ans,(k+get0(l,r)-get1(l,r)));

}printf("%d\n",min(ans,sum[n]));

}return0;}

int get0(int l,int r)

int get1(int l,int r)

int min(int a,int b)

int max(int a,int b)

翻轉字串的解法

char reversestring char pstr return pstr char reversestring char pstr assert pstr null int len strlen pstr char p pstr static int i 1 用於p len i,p len ...

FJ的字串(遞迴解法)

問題描述 fj在沙盤上寫了這樣一些字串 a1 a a2 aba a3 abacaba a4 abacabadabacaba 你能找出其中的規律並寫所有的數列an嗎?輸入格式 僅有乙個數 n 26。輸出格式 請輸出相應的字串an,以乙個換行符結束。輸出中不得含有多餘的空格或換行 回車符。樣例輸入 樣例...

字串內特殊字元處理

問題描述 輸入乙個字串,裡面包含特殊字元 對每個字串作如下處理 1.如果遇到 則刪除 之前的所有字元 包括 2.如果遇到 則刪除 之前的乙個字元 包括 問題分析 最直接的辦法,遍歷整個字串,遇到 再做相應處理,處理可以是直接刪除,但需要注意的是,如果直接刪除,刪除會改變字串大小,遍歷字串則應該注意。...