zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 73 (Rated for Div. 2)

    D. Make The Fence Great Again

    http://codeforces.com/contest/1221/problem/D

    题意:给出n个篱笆,每个篱笆高度为a,一米的造价为b,要求相邻的两个篱笆高度不能相同,且每个篱笆的高度只能增加,求符合条件的最小造价;

    思路:首先:可以确定的是每个篱笆的增加高度不会大于2。例如:假设一个篱笆高度为1,左边为1,右边为2,则它的增加高度为2。如果左右都为1,只需增加1。知道了篱笆的最大增加高度,就可以用DP解决问题。设一个dp[ i ][ j ],意为[1, i ]个篱笆符合条件并且第i个篱笆增加j高度的最小造价,数组pre[ i ]表示第i个篱笆增加k个单位后的高度(0<=k<=2),故可得转移方程:dp(i,j)=jb+min{dp(i1,k)|k[0;2]}

     

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int N=300005;
    ll INF=1e18;
    int n,t;
    int a,b;
    ll dp[N][3];//dp[i][j]表示第i个增j高度的最小造价
    int pre[3];//pre[j]表示当前篱笆高度增加j
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            scanf("%d%d",&a,&b);
            pre[0]=a;
            pre[1]=a+1;
            pre[2]=a+2;
            dp[1][0]=0;
            dp[1][1]=b;
            dp[1][2]=2*b;
            for(int i=2;i<=n;i++)
            {
                scanf("%d%d",&a,&b);
                dp[i][0]=dp[i][1]=dp[i][2]=INF;
                for(int j=0;j<3;j++)
                {
                    if(pre[j]!=a)
                    {
                        dp[i][0]=min(dp[i][0],dp[i-1][j]);
                    }
                }
                for(int j=0;j<3;j++)
                {
                    if(pre[j]!=a+1)
                    {
                        dp[i][1]=min(dp[i][1],b+dp[i-1][j]);
                    }
                }
                for(int j=0;j<3;j++)
                {
                    if(pre[j]!=a+2)
                    {
                        dp[i][2]=min(dp[i][2],b+b+dp[i-1][j]);
                    }
                }
                for(int j=0;j<3;j++)
                {
                    pre[j]=a+j;
                }
            }
            printf("%lld
    ",min(dp[n][0],min(dp[n][1],dp[n][2])));
        }
        return 0;
    }
    View Code

     E:Game With String

    http://codeforces.com/contest/1221/problem/E

    standard output

    Alice and Bob play a game. Initially they have a string s1,s2,,sns1,s2,…,sn, consisting of only characters . and X. They take alternating turns, and Alice is moving first. During each turn, the player has to select a contiguous substring consisting only of characters . and replaces each of them with X. Alice must select a substing of length aa, and Bob must select a substring of length bb. It is guaranteed that a>ba>b.

    For example, if s=s= ...X.. and a=3a=3, b=2b=2, then after Alice's move string can turn only into XXXX... And if it's Bob's turn and the string s=s= ...X.., then after Bob's move the string can turn into XX.X.., .XXX.. or ...XXX.

    Whoever is unable to make a move, loses. You have to determine who wins if they both play optimally.

    You have to answer qq independent queries.

    Input

    The first line contains one integer qq (1q31051≤q≤3⋅105) — the number of queries.

    The first line of each query contains two integers aa and bb (1b<a31051≤b<a≤3⋅105).

    The second line of each query contains the string ss (1|s|31051≤|s|≤3⋅105), consisting of only characters . and X.

    It is guaranteed that sum of all |s||s| over all queries not exceed 31053⋅105.

    Output

    For each test case print YES if Alice can win and NO otherwise.

    You may print every letter in any case you want (so, for example, the strings yEs, yes, Yes and YES will all be recognized as positive answer).

    Example
    input
    Copy
    3
    3 2
    XX......XX...X
    4 2
    X...X.X..X
    5 3
    .......X..X
    
    output
    Copy
    YES
    NO
    YES
    
    Note

    In the first query Alice can select substring s3s5s3…s5. After that ss turns into XXXXX...XX...X. After that, no matter what move Bob makes, Alice can make the move (this will be her second move), but Bob can't make his second move.

    In the second query Alice can not win because she cannot even make one move.

    In the third query Alice can choose substring s2s6s2…s6. After that ss turns into .XXXXX.X..X, and Bob can't make a move after that.

    题意:有一字符串,Alice和Bob轮流操作,Alice可将连续的长度为a的'.'字符变成'X',Bob可将连续的长度为b的'.'字符变成'X',当一方不可操作时游戏结束,Alice先操作,问她能否获得胜利。

    思路:

    情况1:当存在长度为len且b=<len<a的字符片段时,Bob一定能获得胜利。(B的操作是完全可以覆盖A的,也就是说,这个len长的字符是Bob的后手,如果B除此之外无路可走,他就可以改变这个字符片段,获得胜利)。

    情况2:当存在至少两个长度为len且len>=2*b的字符片段时,Bob依然胜利。(对于一个长度为len的字符片段,如果Bob先手,他能将字符片段变为情况1)。

    情况3:没有长度为len>=2*b的字符片段,根据长度2*b>len>a的数量奇偶判断。(这种情况很容易理解,每个字符片段只允许一个人操作一次)

    情况4:只有一个长度为len>=2*b的字符片段。(A先手,遍历这个字符片段,然后返回情况3判断)。

    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<queue>
    using namespace std;
    int q,a,b,len;
    int cnta,cntb,cnt1,cnt,maxx;
    const int N=300010;
    char str[N];
    int main()
    {
        scanf("%d",&q);
        while(q--)
        {
            maxx=cnta=cntb=cnt1=cnt=0;
            scanf("%d%d%s",&a,&b,(str+1));
            len=strlen(str+1);
            str[len+1]='X';
            for(int i=1;i<=len+1;i++)
            {
                if(str[i]=='.')
                    cnt++;
                else
                {
                    if(cnt>=a)
                        cnta++;
                    if(cnt>=b)
                        cntb++;
                    if(cnt>=2*b)
                        cnt1++;
                    maxx=max(cnt,maxx);
                    cnt=0;
                }
            }
            if(cnta<cntb)//存在  b<=len<a
            {
                printf("NO
    ");
                continue;
            }
            if(cnt1>=2)// 存在两个 len>=2*b
            {
                printf("NO
    ");
                continue;
            }
            else
            {
                if(cnt1==1)// len>=2*b>=a
                {
                    int flag=0;
                    for(int i=0;i<=maxx-a;i++)
                    {
                        int l=i;
                        int r=maxx-a-i;
                        if(l>=2*b||r>=2*b)
                            continue;
                        if((l>=b&&l<a)||(r>=b&&r<a))
                            continue;
                        int temp=0;
                        if(l>=a)
                            temp++;
                        if(r>=a)
                            temp++;
                        if((cnta+temp-1)%2==0)//此处还减一是因为这个字符片段本身满足a=<len<2*b
                        {
                            flag=1;
                            break;
                        }
                    }
                    if(flag)
                        printf("YES
    ");
                    else
                        printf("NO
    ");
                }
                else
                {
                    if(cnta%2)
                    {
                        printf("YES
    ");
                    }
                    else
                        printf("NO
    ");
                }
            }
        }
    }
    View Code
  • 相关阅读:
    vue-router 实践
    修改vue中<router-link>的默认样式
    JSON.parse() 与 JSON.stringify() 的区别
    JS 中的异步操作
    CSS3 box-sizing:border-box的好处
    element ui 栅格布局
    css overflow用法
    koa中间件机制
    canvas 入门
    前端面试题:淘宝首页用了多少种标签
  • 原文地址:https://www.cnblogs.com/switch-waht/p/11558185.html
Copyright © 2011-2022 走看看