Codeforces Round 866 (Div. 2) A~C

 这场,非常快落!是难得对中国选手友好的时间(17:05)

 

A观察一下,发现在连续的___中插入^就好,然后特判一下首尾,发现很像小学奥数的那个植树问题哇(

注意特判一下只有一个^

#include<bits/stdc++.h>
using namespace std;
void solve(){
    string s;
    cin>>s;
    int n=s.length();
    int ans=0;
    if(n==1&&s[0]=='^') {
        cout<<1<<endl;return;
    }
    if(s[0]=='_') ans++;
    if(s[n-1]=='_') ans++;
    int pre=0;
    for(int i=0;i<n;i++){
        if(s[i]=='_') pre++;
        else {
            //cout<<i<<" "<<pre<<endl;
            ans+=max(pre-1,0);
            pre=0;
        }
    }
    ans+=max(pre-1,0);
    cout<<ans<<endl;
}
int main(){
    //freopen("lys.in","r",stdin);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
} 

 

B的话是观察了样例后猜的结论,但是越猜越对,最开始感觉只跟最长的连续1有关(因为只要有0就断掉了)

然后考虑一下如果有一段连续1,会怎么操作?其实是慢慢挪动,有一个错位的效果

假如有4个1,那么有5=1+4,5=2+3,5=3+2,5=4+1,矩形的面积可能有1*4,2*3

显然和一定,两个数尽量相近的时候取最大。

但光是这样是过不了样例的,因为存在特殊情况使得头和尾都是1,这种情形下其实是连在一起的

那就破环成链,复制一遍后再算

但这样又会wa2,测了一个全是1的样例,发现这样会多算,所以还要特判是否全为1

然后在跌跌撞撞的猜测和快落的讨论中,虽然对结论不是很有底,竟然Accepted了

#include<bits/stdc++.h>
using namespace std;
int main(){
    //freopen("lys.in","r",stdin);
    
    int t;
    cin>>t;
    while(t--){
        string t,s;
        cin>>t;
        s=t+t;
        long long n=t.length(),pre=0,mx=0;
        if(n==1){
            if(s[0]=='1') cout<<1<<endl;
            else cout<<0<<endl;
            continue;
        }
        for(int i=n;i<2*n;i++) s[i]=s[i-n];
        if(s[0]=='1') pre=1,mx=1;
        for(int i=1;i<2*n;i++){
            if(s[i]=='1'){
                pre++;
                mx=max(pre,mx);
            }
            else pre=0;
        }
        if(mx==2*n){
            cout<<n*n<<endl;
            continue;
        }
        mx++;
        if(mx%2==0) cout<<mx*mx/4<<endl;
        else cout<<(mx/2)*(mx/2+1)<<endl;
    }
}

 

C的题目名字告诉你,这是一道构造题(这是能说的吗

考虑如果要使得mex+1,那要复制的k肯定是mex,否则mex之前都没出现过,之后也不会出现过

那又分出了一些情况:

1.如果存在一些数=mex+2,是不是都要覆盖掉?否则就不是+1,可能+234了

那就从最左边的mex+2开始,一直赋值到最右边的mex+2

然后再重新算一遍当前mex是否满足条件(因为在覆盖过程中,可能会覆盖本来不应该覆盖的数)

2.假如没有的话,那只要挑>mex+2的数赋值为mex+1就好了

假如也没有>mex+2的数,那挑一个<mex的至少出现一次的赋值就好了

那要是也没有,则说明了当前是0,1,2,3,4...这种形式,必然有mex==n,特判一下就好。

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=200005;
int n,a[maxn];
map<int,int>cnt;
bool solve(){
    cnt.clear();
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],cnt[a[i]]=1;
    int mex;
    for(int i=0;i<=min(n,200000);i++) if(!cnt[i]) { mex=i;break; }
    // part1: exit x that x==mex+1
    bool flag1=false;
    //cout<<mex<<endl;
    for(int i=1;i<=n;i++) if(a[i]==mex+1) flag1=true;
    if(flag1){
        int left=0,right=0;
        for(int i=1;i<=n;i++) if(a[i]==mex+1) { left=i;break;}
        for(int i=n;i>=1;i--) if(a[i]==mex+1) { right=i;break;}
        cnt.clear();
        for(int i=1;i<left;i++) cnt[a[i]]=1;
        for(int i=right+1;i<=n;i++) cnt[a[i]]=1;
        cnt[mex]=1;
        int newmex;
        for(int i=0;i<=min(n,200000);i++) if(!cnt[i]) { newmex=i;break; }
        if(newmex==mex+1) return true;
        else return false;
    }
    bool flag2=false;
    for(int i=1;i<=n;i++) if(a[i]>=mex+2) flag2=true;
    if(flag2){
        return true;
    } 
    if(mex==n) return false;
    else return true;
}
int main(){
    //freopen("lys.in","r",stdin);
    int t;
    cin>>t;
    while(t--){
       if(solve())     cout<<"Yes"<<endl;
       else cout<<"No"<<endl;
    }
}

 

D.发现小猫没说全题意时,我们已经卡了半小时了哈哈哈哈

趁着修猫上厕所突发奇想重新看了一遍题()

本来以为是纯拼图,后面发现每次其实是取当前的长和宽,这还是很不一样的

现场猜dfs+线段树维护最大值可做,并且答案肯定有一个数是x的最大值或者y的最大值

后面想想又觉得甚至不用dfs,每次的决策甚至可能只有一步,找个时间补一下~~

 

posted @ 2023-04-16 09:40  liyishui  阅读(89)  评论(0编辑  收藏  举报