2018.08.30 【校内模拟】T1 万里长城 (队列)

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82220167

【问题描述】

万里长城是中国强大的标志,长城在古代的用途主要用于快速传递军事消息和抵御
外敌,在长城上的烽火台即可以作为藏兵的堡垒有可以来点燃狼烟传递消息。 现在有一段
万里长城,一共有 N 个烽火台,有些烽火台里驻扎有士兵,而有一些烽火台没有驻扎。一
次将军巡视时发现了一个巨大的防卫漏洞,一个烽火台狼烟点燃后,并不是任意一个烽火
台就能看见,当距离超过 D 后就不能看见了,为了保证第一个烽火台的狼烟点燃后能顺利
传递到第N 个烽火台,将军必须要在一些没有驻扎士兵的烽火台中安排士兵驻扎。
长城中一共有 N 个烽火台,第 1 个烽火台和第 n 个烽火台中一定驻扎着士兵,每个烽火台直接距离是 1,将军必须安排士兵到一些烽火台使得第 1 个烽火台的狼烟能顺利传递到第 n 个烽火台,不过由于长城太长了,将军没有太多的士兵来安排,所以他求助于你,希望你计算出 安排士兵最少的烽火台数量。

【输入格式】

第一行是2 个整数N,D,表示一共N 个烽火台,狼烟能传递的最长距离D
接下来一行是 N 个数 0 或 1,表示第 i 个烽火台是否驻扎士兵,1 表示驻扎了士兵,0 表示没有驻扎。数据保证第1 个和第N 个一定是1

【输出格式】

1 个整数表示安排士兵的最少烽火台数量

【输入样例1】

4 1
1 0 1 1

【输出样例1】

1

【输入样例2】

8 2
1 1 0 0 1 0 0 1

【输出样例2】

2

【数据规模】

20%数据 N<=20
50%数据 N<=1000
100%数据,N<=300 000 ,1<=D<=N


解析:

签到题。

做法很多,这里放出我写的两份代码,都是队列。


代码1:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
#define st static

inline
ll getint(){
    re ll num=0;
    re char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);c=gc())num=(num<<1)+(num<<3)+(c^48);
    return  num;
}

inline
void outint(ll a){
    st char ch[23];
    if(a==0)pc('0');
    while(a)ch[++ch[0]]=(a-a/10*10)^48,a/=10;
    while(ch[0])pc(ch[ch[0]--]);
}

int N,D;
bool a[300003];
int head,tail;
int cnt;
int Ans;

int main(){
    N=getint();
    D=getint();
    for(int re i=1;i<=N;++i)a[i]=getint();
    ++head;
    while(head<=N&&tail<=N){
        while(a[head]&&head<N)++head;
        if(head>=N)break;
        tail=head;
        while(!a[tail+1])++tail;
        if(tail>N)break;
        Ans+=(tail-head)/D;
        ++head;
    }
    outint(Ans);
    return 0;
}

代码2:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
#define st static

inline
ll getint(){
    re ll num=0;
    re char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);c=gc())num=(num<<1)+(num<<3)+(c^48);
    return  num;
}

inline
void outint(ll a){
    st char ch[23];
    if(a==0)pc('0');
    while(a)ch[++ch[0]]=(a-a/10*10)^48,a/=10;
    while(ch[0])pc(ch[ch[0]--]);
}

int N,D;
bool a[300003];
bool q[300003];
int head,tail;
int cnt;
int Ans;

int main(){ 
    N=getint();
    D=getint();
    for(int re i=1;i<=N;++i)a[i]=getint();

    if(a[1])++cnt;
    q[++tail]=a[1];
    for(int re i=2;i<=N;++i){
        if(tail-head>D){
            if(q[++head])--cnt;
        }
        if(cnt==0){
            ++cnt;
            ++Ans;
            q[tail]=1;
        }
        if(a[i]){
            ++cnt;
            q[tail+1]=1;
        }
        else{
            q[tail+1]=0;
        }
        ++tail; 
    }
    outint(Ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/82220167