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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

H - Checker FZU - 2041

發(fā)布時(shí)間:2023/12/3 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 H - Checker FZU - 2041 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

H - Checker FZU - 2041

題意:

一個(gè)長度為n的01串,現(xiàn)在能將里面的1移動m次,問最長的連續(xù)0是多長

題解:

沒想出來,看了其他人代碼,就是對于每個(gè)0空間進(jìn)行擴(kuò)充,然后記錄每次擴(kuò)充的最大值
關(guān)鍵在于擴(kuò)充的細(xì)節(jié):
我們每次鎖定一個(gè)連續(xù)的0的左右端點(diǎn)(圖中的left和right)
然后看left和right分別向外找最近的0,我們可以通過下圖看出,左側(cè)長度為lena可以找到0,右側(cè)lenb可以找到0,lena<lenb,所以我們移動左側(cè)
每次移動也是緩慢移動,我們讓i和j進(jìn)行交換,然后看left-1(即k的位置)是否為0,如果是0,left就向左移動,相當(dāng)于擴(kuò)大區(qū)間,
為什么要先交換i和j呢?因?yàn)橐獢U(kuò)大范圍,只能先換走j,再換走k,一步一步來,不能著急,每次移動都會消耗步數(shù)

這個(gè)思路很妙

代碼:

#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <vector> using namespace std;typedef long long LL; const double eps = 1e-6; const int INF = 0x3f3f3f3f; const int MAXN = 500 + 10; int t, len, step; char G[MAXN], CG[MAXN];int Calc(int left, int right) {strcpy(CG, G);int cnt = step;int low = left - 1, high = right + 1;while (cnt--) {if (low - 1 < 0 && high + 1 >= len) break;for (;;) {if (low - 1 < 0 && high + 1 >= len) break;int lena = INF, lenb = INF;bool yes = false;if (low - 1 >= 0 && CG[low - 1] == '0') {//記錄兩個(gè)0之間相隔1的數(shù)量 lena = left - (low - 1);yes = true;} if (high + 1 < len && CG[high + 1] == '0') {lenb = high + 1 - right;yes = true;}if (!yes) {//如果low和high還沒找到0,繼續(xù)向外找 --low;++high;continue;}if (lena < lenb) {//相隔1最少的 swap(CG[low], CG[low - 1]);if (CG[left - 1] == '0') {//查看left是否可以向左擴(kuò)展 --left;}} else {swap(CG[high], CG[high + 1]);if (CG[right + 1] == '0') {++right;}}low = left - 1;high = right + 1;break;}}return right - left + 1; }int main() {scanf("%d", &t);int cas = 0;while (t--) {scanf("%d%d%s", &len, &step, G);int ans = 0;for (int i = 0; i < len;) {if (G[i] == '0') {int j = i;while (j + 1 < len && G[j + 1] == '0') { ++j; }//每次找到連續(xù)0的左右端點(diǎn) ans = max(ans, Calc(i, j));i = j + 1;} else {++i;}}printf("Case %d: %d\n", ++cas, ans);}return 0; }

總結(jié)

以上是生活随笔為你收集整理的H - Checker FZU - 2041的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。