二分 - Enduring Exodus - CodeForces - 655C

二分 - Enduring Exodus - CodeForces - 655C

題意:

nm首行輸入包括兩個整數n和m,分別爲房間的數量和牛的數量。

n0101第二行包含一個長度爲n的01串,'0'表示房間爲空,'1'表示房間不空。

mn使現有一人與m頭牛,要住在這n個房間中的空房間中,要求使得所有牛中距離主人房間最遠的距離儘量小。

求出這個最小最遠距離。

數據範圍:

1<=n,m<=100000Time limit2000msMemory limit262144kB1<=n,m<=100000\\Time\ limit:2000 ms,Memory \ limit:262144 kB

Examples

Input:
7 2
0100100
_______
Output:
2

Input:
5 1
01010
_______
Output:
2

Input:
3 2
000
_______
Output:
1

分析:

kk+1若最遠距離爲k時能夠住下,那麼最遠距離爲k+1時也一定能夠住下。

因此二分答案。

imidmidr=midl=mid+1枚舉主人的位置i,接着二分最遠距離mid,若mid可行則r=mid,反之l=mid+1。

checkmid關鍵問題在於check函數如何寫,判斷mid是否可行。

i[imid,i+mid]m+10mid對於枚舉的主人位置i,判斷一下[i-mid,i+mid]這個區間內是否存在m+1個0,若存在,說明mid可行。

00因爲要頻繁的查詢某段區間內'0'的數量,故先用前綴和預處理區間'0'的數量。

代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>

#define ll long long
#define P pair<int,int>
#define l first
#define r second
#define inf 0x3f3f3f3f

using namespace std;

const int N = 100010;

int n,m,sum[N];
char s[N];

bool check(int pos,int len)
{
    int l=max(1,pos-len),r=min(n,pos+len);
    return (sum[r]-sum[l-1]>=m+1);
}

int main()
{
    cin>>n>>m;
    scanf("%s",s+1);
    for(int i=1;s[i];i++)
            sum[i]=sum[i-1]+(s[i]=='0');

    int res=n;
    for(int i=1;i<=n;i++)
        if(s[i]=='0')
        {
            int l=1,r=n;
            while(l<r)
            {
                int mid=l+r>>1;
                if(check(i,mid)) r=mid;
                else l=mid+1;
            }
            res=min(res,l);
        }

    cout<<res<<endl;

    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章