• Codeforces Round #721 (Div. 2)题解


    比赛链接

    wa得老惨了qwq,本来还以为只能一题,太惨了太惨了

    A. And Then There Were K

    给你一个n,求最大的k使得:

    思路:求n二进制最高位对应的数-1

    int n;
    void solve()
    {
        sd(n);
        int nn=n,val=1;
        while(nn)
        {
            val<<=1;
            nn>>=1;
        }
        val>>=1;
        pd(val-1);
    }

    B1. Palindrome Game (easy version)

    给你一个01回文串

    想要将这个字符串变为全1

    两个操作:

    1、将其中一个0变为1,花费1

    2、当该字符串不是回文串且上一个操作不是2则可将该字符串反转,花费0

    ALICE先手

    最后花费最少的人获胜

    思路:因为当前是回文,所以ALICE第一次必花费

    cnt代表0的个数,当cnt是奇数代表中间是0

    cnt为1时只能只有ALICE操作

    当cnt为2时的操作为(1)ALICE花费1(2)BOB反转(3)ALICE花费1

    当cnt为偶数且cnt>2时,BOB每次选择ALICE对应的位置的0变为1,直到cnt为2

    当cnt为奇数时,ALICE选择中间的0变为1,然后风水轮流转,cnt变为偶数,自行代入上面的情况hhh

    当cnt=1时花费为1:0

    当cnt为奇数时花费差1

    当cnt为偶数时花费差2

    int n;
    char s[maxn];
    void solve()
    {
        sd(n);
        sc(s+1);
        int cnt=0;
        rep(i,1,n)if(s[i]=='0')cnt++;
        if(cnt==1)puts("BOB");
        else if(cnt&1)puts("ALICE");
        else puts("BOB");
    }

    B2. Palindrome Game (hard version)

    题意同上,只是原来的串不一定是回文串

    int n,cnt,cnt1;
    char s[maxn];
    void solve()
    {
        sd(n);
        sc(s+1);
        cnt=cnt1=0;
        rep(i,1,n)
        {
            if(s[i]=='1')continue;
            if(s[i]==s[n-i+1])cnt++;
            else cnt1++;
        }
        if(cnt1>=2||!cnt)
        {
            puts("ALICE");
            return;
        }
        if(cnt1==1)
        {
            if(cnt==1)puts("DRAW");
            else puts("ALICE");
            return;
        }
        if(cnt==1)puts("BOB");
        else if(cnt&1)puts("ALICE");
        else puts("BOB");
    }

    cnt为该位置为0且对应位置为0的个数

    cnt1为该位置为0且对应位置为1的个数

    当cnt为0时,按上一题解法

    因为当cnt1>=3时,ALICE先每次都选择反转,BOB只能选择cnt1对应位置的0变为1,直到变为回文串,这时比分已经是0:cnt1了,BOB不可能反败为胜

    当cnt1=2时,如果cnt为奇数,等到变为回文串时,ALICE是先手,具体同上一题;如果cnt为偶数,那么ALICE在第二次操作时选择将另一个cnt1的0变为1,然后变成的情况可参考上一题

    当cnt1=1时,如果cnt为奇数,同上;否则ALICE第一步直接选择将这个0变为1,然后就变成的情况可参考上一题

    C. Sequence Pair Weight

    给一个长度为n的数组,区间[l,r]的值为在这区间内,ai=aj的对数

    让你求对于所有的子区间的值和。

    害,这题有点难讲啊,毕竟我也是混过去的(不会吧不会吧,不会有人要来hack我吧),暂时先只放代码吧

    int n,a[maxn];
    int l[maxn],pre[maxn],cnt[maxn];
    ll ans,sum[maxn];
    void solve()
    {
        sd(n);ans=0;
        rep(i,1,n)sd(a[i]),l[i]=a[i];
        sort(l+1,l+1+n);
        int m=unique(l+1,l+1+n)-l-1;
        rep(i,1,m)pre[i]=0,sum[i]=0;
        ll sum1=0;
        rep(i,1,n)
        {
            int k=lower_bound(l+1,l+1+m,a[i])-l;
            ans+=sum1;
            sum[k]+=pre[k];
            ans+=sum[k];
            pre[k]=i;
            sum1+=sum[k];
        }
        plld(ans);    
    }
    欢迎加我qq1165750856一起玩呀~
  • 相关阅读:
    【笔记】nRF24L01软件初始化
    【笔记】关于DSP连接CMD文件及连接存储块的理解
    【笔记】CCS4 出现 warning: entrypoint symbol other than "_c_int00" specified: "code_start" 的解决方法
    【转载】低压电流互感器实用技术问答30例
    【笔记】1、防止电压反充电,2、前后加速,3、开口三角PT(TV)原理
    Linux虚拟文件系统及其实例XORFS
    LINUX内核狂想曲之SLOB分配器
    程序的思想决定程序的世界
    LINUX内核之内存屏障
    插入排序——平均算法复杂度分析
  • 原文地址:https://www.cnblogs.com/HHHEN/p/14792151.html
Copyright © 2020-2023  润新知