为了能到远方,脚下的每一步都不能少.|

园龄:粉丝:关注:

牛客周赛 Round 73

写的很拉跨的一次

A

在区间内枚举,找到一个数%x==0就是满足题意

B

这题嗯......,学会看题面(重要教训
限制了答案范围$(1<=l<=r<=2e9),所以为了尽可能的找到答案l,r尽量要小
为了满足区间条件,那么区间长度是大于n*x

若k/x==n,那么[1,k]则满足题意
或者第二小的右端点x+k-1,那么[x,x+k-1]则满足题意
其他区间也可以,那么前面的两种区间也可以满足题意
如果前面的区间都不行,那么就没有可以满足题意得了

#include<bits/stdc++.h>
 
using namespace std;
#define ll long long 
unsigned ll x,k;
unsigned ll n;
int main(){
    cin>>n>>k>>x;
    if(k/x==n){
        cout<<1<<" "<<k<<endl;
    }
    else if((x+k-1)/x==n) cout<<x<<" "<<x+k-1<<endl;
    else cout<<"-1"<<endl;
    return 0;
}

C

其实给定的一个01串分四种类型,
...00001...
...11111...
...10000...
...00000...

一个字符串就可以用这几种类型组成
我们只需要找到一个成立即可

  1. 对于第一种类型
    每个0的位置按顺序取下一个数,1取第一个0的数
    比如 001
    构造的序列 321

  2. 对于第二种类型
    每个1的位置取当前的数
    比如 111
    123

  3. 对于第三种类型
    如果最后的0没有1在后面那么无解(原因很好想
    如果有1,那么每个0仍然可以取下一个数,1取本身的数
    比如 10000...
    13456

  4. 对于第四种类型
    每个0取后一个数

如果我们随意组合四种类型,发现这样并不矛盾,所以我们可以构造的序列的原则
0取下一位数,1取本身的数,如果0在最后一位无解

#include<bits/stdc++.h>

using namespace std;
#define ll long long 
int n;
string s;
const int maxn=1e5+10;
int f[maxn];
int main(){
    cin>>n;
    cin>>s;
    s=" "+s;
    for(int i=1;i<=n;++i){
        if(s[i]=='0') {
            if(i==n){
                cout<<"-1"<<endl;
                return 0;
            }
            int j=i;
            while(i<n && s[i+1]=='0'){
                f[i+1]=i;
                ++i;
            }
            if(s[i+1]=='1') f[j]=i+1,f[i+1]=i;
            ++i;
        }
        else if(s[i]=='1') f[i]=i;
    }
    for(int i=1;i<=n;++i) cout<<f[i]<<" ";
    return 0;
}

D

这个题感觉有点绕啊
应该这样说明题目更好

一个区间内,任取0,1,且0的位置总是小于1,就可以构成一对01,请问是否能找到一个区间内有k对01串
我们最终找到的区间是000000111100111111,无数个连续0,1重复出现

我们思考一下,这样的区间怎么产生答案
对于第一个1,前面的所有0,对答案有贡献,其他的1都是如此
但是每一个1,前面的所有0,统计前面的0

那么如何寻找这样一个区间,按照暴力的思路,我们固定一个左端点,逐渐移动右端点
如果右端点是1,那我们那么加上前面的0的数量
如果右端点是0,0的数量++
一旦数量超出我们所求,就移动左端点,重新移动右端点
显然这样会超时

这里可以借鉴滑动窗口的思想,超出所求时,移动左端点
如果左端点原来是0,就减去1的数量,如果是1,1的数量--
这样避免了重新移动右端点,减少移动时间,并且不会漏解


#include<bits/stdc++.h>

using namespace std;
#define  ll long long 
int n;
ll k;
string s;
int main(){
    cin>>n>>k;
    int l=1,r=1;
    cin>>s;
    s=" "+s;
    ll c0=0,c1=0,cnt=0;
    while(r<=n){
        while(r<=n && cnt<k){
            c0+=s[r]=='0';
            c1+=s[r]=='1';
            cnt+=s[r]=='1'?c0:0;
           ++r;
        }
        if(cnt==k){
            cout<<l<<" "<<r-1<<endl;
           return 0;
        }
        while(cnt>k){
            c0-=s[l]=='0';
            c1-=s[l]=='1';
            cnt-=s[l]=='0'?c1:0;
            ++l;
        }
    }
    cout<<"-1"<<endl;
    return 0;
}

本文作者:归游

本文链接:https://www.cnblogs.com/guiyou/p/18624605

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   归游  阅读(18)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起