ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-07-24 18:02:21  阅读:155  来源: 互联网

标签:Educational Rated 前缀 int wh 括号 read 补题 --


 加粗:赛时AC 

普通:赛后AC

A. Three Doors

水题,但我一开始没看懂题意,就随便猜了个题意。反正就是拿着钥匙开一扇门,门后有别的钥匙,问你能不能全打开。

int main()
{
    read(t);
    while(t--)
    {
        int x;
        read(x);
        memset(buc,0,sizeof(buc));
        for(int i=1;i<=3;i++) read(a[i]);
        buc[x]=1;
        buc[a[x]]=1;
        buc[a[a[x]]]=1;
        //buc[a[a[a[x]]]]=1;
        bool flag=1;
        for(int i=1;i<=3;i++) if(buc[i]==0) flag=0;
        if(!flag) printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}
View Code

B. Also Try Minecraft

依然没有完全看懂题意,但是模拟了一下样例,就是一个前缀和后缀和的问题,统计之间的差值。

int main()
{
    read(n);read(m);
    for(int i=1;i<=n;i++) read(a[i]);
    for(int i=1;i<=n;i++)
    {
        if(a[i]>a[i+1]) p[i]=p[i-1]+(a[i]-a[i+1]);
        else p[i]=p[i-1];
    }
    for(int i=n;i>=1;i--)
    {
        if(a[i]>a[i-1]) rp[i]=rp[i+1]+(a[i]-a[i-1]);
        else rp[i]=rp[i+1];
    }
    for(int i=1;i<=m;i++)
    {
        ll x,y;
        read(x);read(y);
        if(x<y) printf("%lld\n",p[y-1]-p[x-1]);
        else printf("%lld\n",rp[y+1]-rp[x+1]);
    }
    return 0;
}
View Code

C. Recover an RBS

关于括号匹配,要遵循两个要点,一是一定要保证每个位置的左括号前缀和大于右括号的,第二点是最终左右括号个数相等。

这题我是这样考虑的。

题目给了一个很重要的条件,就是保证了必定存在至少一种情况符合匹配的模式串,那么如果答案唯一,应该是哪一种?

我们将左括号看做+1,右括号看做-1,那么两个要点就变为了任何地方的前缀和大于1并且最终前缀和为0。

显然,对于所有的?,我们可以根据左括号和等于右括号和,算出这当中有多少左右括号,然后将在前面等量的?换为需要的(,在后面的换为),这必定是一种可行的情况。

然后计算这个序列的前缀和,如果我们要变换我们填上的括号的方向,一定是将一组()变为)(,此时在这之中的所有前缀和都要-2,如果有负数,就不能变换。

显然我们应该变换位于中间的一组问号变得括号,此时削减的前缀和最少并且与其他的括号组合是被包含的关系。

int main()
{
    read(T);
    while(T--)
    {
        a=0;b=0;
        cin>>s;
        int len=s.size();
        for(int i=0;i<len;i++)
        {
            p[i]=0;
            if(s[i]=='(') a++;
            else if(s[i]==')') b++;
        }
        a=len/2-a;b=len/2-b;
        bool flag=0;
        int las=0;
        for(int i=0;i<len;i++)
        {
            p[0]=1;
            if(s[i]=='?')
            {
                if(a) {a--;if(i!=0)p[i]=p[i-1]+1;if(a==0) las=i;}
                else {b--;p[i]=p[i-1]-1;}
            }
            else if(s[i]=='(') p[i]=p[i-1]+1;
            else p[i]=p[i-1]-1;
        }
        for(int i=las;i<len;i++)
        {
            if(s[i]=='?'&&i!=las) break;
            if(p[i]<2)  flag=1;
        }
        if(!flag) printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}
View Code

队友给了我一个别的思路,代码更加简洁一些,但是中心思想还是两个要点:

从左到右运行的时候,设置两个计数变量num1和num2,遇到'(',num1++,遇到')',num1--,遇到'?',num2++。

遇到对于第i位,如果此时num1+num2==1,意味着此时剩下的)比?个数小1,在那么显然为了满足括号匹配条件1,所有的问号应该都是右括号,我们就可以将这一部分的计数重置为num1=1,num2=0,意味着前i项的?是固定不变的。

运行到最后,如果剩下的'('或者')'数量和'?'数量一致,那么?是固定不变的,否则括号的数量会小于问号数量,意味着问号是可以变方向的。

void solve() {
    cin >> s + 1;
    int n = strlen(s + 1);
    int wh = 0, cnt = 0;
    rep(i, 1, n) {
        if (s[i] == '(')
            wh++;
        else if (s[i] == ')')
            wh--;
        else
            cnt++;
        if (wh + cnt == 1) wh = 1, cnt = 0;
    }
    if (abs(wh) == cnt)
        cout << "YES\n";
    else
        cout << "NO\n";
}
 
View Code

D. Rorororobot

这题反而比上题思路清晰点。

题目给出的障碍物是挨着地面的,然后行动的参数是每次都行动k格。

那么我们首先要确定没有障碍物的情况下能否到达,机器人智能走上下左右四个方向,那么起点终点的坐标对k取模一定要相等。

其次由于不要求我们最低的步数,我们每次都可以将机器人升到最高的位置去跨越这些障碍,到达终点的上方,这就需要我们算出起始列到终点列的最高障碍物,可以用ST表进行维护。

注意哪个是横坐标,那个是纵坐标。。。

inline void ycl()
{
    for(int i=1;i<=18;i++)
    {
        for(int j=1;j+(1<<i)-1<=m;j++)
        {
            st[i][j]=max(st[i-1][j],st[i-1][j+(1<<(i-1))]);
        }
    }
}

inline ll search1(ll l,ll r)
{
    ll len=(ll)log2(r-l+1);
    return max(st[len][l],st[len][r-(1<<len)+1]);
}

int main()
{
    read(n);read(m);
    for(int i=1;i<=m;i++) read(a[i]),st[0][i]=a[i];
    ycl();
    read(Q);
    while(Q--)
    {
        ll x,y,xx,yy,k;
        read(x);read(y);
        read(xx);read(yy);
        read(k);
        
        if(xx%k!=x%k||yy%k!=y%k) cout<<"NO"<<endl;
        else
        {
            ll maxx=search1(min(y,yy),max(y,yy));
            ll maxm=max(x,(x%k)+n/k*k);
            if(maxm>n) maxm-=k;
            if(maxm<=maxx) cout<<"NO"<<endl;
            else cout<<"YES"<<endl;
        }        
    }
    return 0;
}
View Code

 

标签:Educational,Rated,前缀,int,wh,括号,read,补题,--
来源: https://www.cnblogs.com/ztlsw/p/16514929.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有