Educational Codeforces Round 137 (Rated for Div. 2)(补题中)

战绩:

 

A. Password

列出所有可能的形式,包括AABB,ABAB,ABBA三种,然后在所有可行的数字中选两个进行排列,答案即$3*P_n^2$

当然暴力打表也是可以的,这题居然卡了那么久。

int main()
{
    read(T);
    while(T--)
    {
        read(n);
        for(int i=1;i<=n;i++) read(k);
        int lim=3*(10-n)*(10-n-1);
        cout<<lim<<endl;
    }
    return 0;
}
View Code

B. Permutation Value

由于我们要的是子区间,所以答案是2,输出1然后倒序n到2即可

int main()
{
    read(T);
    while(T--)
    {
        read(n);
        cout<<1;
        for(int i=n;i>=2;i--) cout<<" "<<i;
        cout<<endl;
    }
    return 0;
}
View Code

C. Save the Magazines

对于一长段的1,我们能拯救的实际上只有最靠近它们的左边的那个0,那对于每一段我们统计所有的1的最小值,和那个0的值作比较然后决定是否交换即可。

int main()
{
    read(T);
    while(T--)
    {
        read(n);
        cin>>s;
        s='*'+s+'0';
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            read(val[i]);
            if(s[i]=='1') ans+=val[i];
        }
        int pos=-1;
        for(int i=1;i<=n+1;i++)
        {
            if(s[i]=='0')    //结算 
            {
                if(!que.empty()&&pos!=-1)
                {
                    int lim=que.top();
                    ans=max(ans,ans-lim+val[pos]);
                }
                while(!que.empty()) que.pop();
                pos=-1;
            }
            else
            {
                if(s[i-1]=='0') pos=i-1;
                que.push(val[i]);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

D. Problem with Random Tests

亚雷吗,这题最关键的信息是它的数据随机生成,给孩子T麻了。

首先我们要把前导0去除了,那么S1很显然应该是去除之后的这个数字,毕竟它的1位数最高。

然后由于S2是S1的一个子串,我们显然一定要让最左边那个0变为1,这然后再去讨论后面的。

我们截取一小段子串,实际上可以看做从最后一位开始每一位或上其前面第k个数字。

这里是我看到随机生成条件前的做法:

我们可以从左往右,对于每个0,它都有一些偏移值k可以使得它变为1,同时也会有一些偏移值由于要让这一位变为1而失效(和前面的0的偏移值取交集可以让两个都变为1)。

这个k实际上是每一位0之前的所有1和它的相对位置,但是由于我们的0要从高位往低位变化,所以实际上不会太多。

如果在某个0变为1的时候的交集为空,偏移值都失效了,那这一位就无法变为0.

由于是相对位置,所有前面有效的偏移值都会一位位的偏移,那么我们就可以使用bitset进行优化。

但是这样的复杂度最劣的情况是前面一半都是1的情况,就会立刻退化为O(N2/64).

结束之后我才发现数据是随机生成的。。。。。

那这样就意味着前面连续1是很少的,最高位的0只能和前面的1或为1,我们把每一个1都对上这个0然后全都暴力做一遍也不会报。

但是我的复杂度更优(叉腰)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<bitset>
#define ll long long 
#define N 501000
using namespace std;
int n,m,k,tot,Q,tt,T;
string s,s2;
bitset<20000>bs,bs2,bs3,bshas;
inline void read(int &p)
{
    p=0;
    int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {p=p*10+(ch-'0');ch=getchar();}
    p*=f;
}

int main()
{
    //read(T);
    T=1;
    while(T--)
    {
        read(n);
        cin>>s;
        tot=0;
        int tot0=0;
        bool f=0;
        tot=0;
        for(int i=0;i<s.size();i++)
        {
            if(s[i]=='0') tot++;
            if(s[i]=='1') break;
        }
        s2=s.substr(tot);
        if(s2.size()==0) {cout<<0<<endl;continue;}
        tot=0;
        for(int i=0;i<s2.size();i++)
        {
            if(s2[i]=='1') tot++;
            if(s2[i]=='0') break;
        }
        if(tot>=(s2.size()+1)/2)
        {
            for(int i=1;i<=s2.size();i++) cout<<1;
            cout<<endl;
            continue;
        }
        tot=0;
        int anstot=0;
        bool flag=0;
        for(int i=0;i<s2.size();i++)
        {
            bshas<<=1;
            if(s2[i]=='1')
            {
                tot++;
                bshas[1]=1;
            }
            else
            {
                if(!flag)
                {
                    flag=1;
                    bs=bshas;
                    s2[i]='1';
                    continue;
                }
                bs3=(bs&bshas);
                if(bs3.count()==0) continue;
                else 
                {
                    bs=bs3;
                    s2[i]='1';
                }
            }
        }
        cout<<s2<<endl;
    }
    return 0;
}
View Code

 

posted @ 2022-10-20 10:28  ztlsw  阅读(23)  评论(0编辑  收藏  举报