Educational Codeforces Round 132 (Rated for Div. 2)

 终榜:

 

A:

题目:

有三扇门和其中一个门的钥匙,每个门后面可能有其他门的钥匙,问能否将三扇门全部打开

思路:

暴力即可

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define T()\
	int tt; \
	cin>>tt; \
	while(tt--)
#define endl "\n"
const int N=105;
int a[N];
int main()
{
    T()
    {
        int x;
        cin>>x;
        for(int i=1;i<=3;i++)cin>>a[i];
        int ct=1;
        while(a[x])//如果当前的钥匙还能继续开门
        {
            ct++;
            x=a[x];
        }
        if(ct==3)puts("YES");//如果开了三扇门
        else puts("NO");
    }
}

B:

题目:

给定n座山的高度以及m次询问

每次询问给定一个l和r(l有可能大于r)

每次你从坐标为 l 的山出发到达坐标为 r 的山,如果你路径上的下一座山比当前山高的话不耗费体力,否则耗费 高度差 的体力,问每次耗费多少

思路:做一个简单的预处理即可

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define T()\
	int tt; \
	cin>>tt; \
	while(tt--)
#define endl "\n"
const ll mod=1e9+7;
const int N=2e6+10;
ll a[N];
ll cnt1[N],cnt2[N];
int main()
{
    // T()
    {
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=2;i<=n;i++)
        {
            if(a[i]>=a[i-1])cnt1[i]=cnt1[i-1];//预处理从前到后的山
            else cnt1[i]=cnt1[i-1]+(a[i-1]-a[i]);
        }
        cnt2[n]=0;
        for(int i=n-1;i>=1;i--)
        {
            if(a[i]>=a[i+1])cnt2[i]=cnt2[i+1];//预处理从后到前的山
            else cnt2[i]=cnt2[i+1]+(a[i+1]-a[i]);
        }
        while(m--)
        {
            int l,r;
            cin>>l>>r;
            if(l<=r)
            {
                cout<<cnt1[r]-cnt1[l]<<endl;//如果出发点在前
            }
            else
            {
                cout<<cnt2[r]-cnt2[l]<<endl;//如果出发点在后
            }
        }
    }
}

C:

题目:

给定一个字符串,里面含有 '('  ,  ')'  ,  '?'三种字符,‘?’可以变成任意的括号(左括号或右括号),问组成合法括号序列的方法是否唯一,

如果唯一打印“YES”,否则打印“NO”,题目保证数据一定有一组解

合法括号定义:设‘(’的数量为a,‘)’的数量为b,对于任意的i,都有a>=b。

思路:

我们可以发现,如果当前序列中 ‘ (’的数量已经为总长度(下面设为 L )的一半了,那么解法一定唯一,如果没有满足上述条件,那么对于前面某些个左括号,若解法唯一,他们一定是‘(’,下面给出证明。

证:对于‘(’数量不到 L /2 时,对于第一个‘?’,我们可以知道这个字符为‘(’时序列一定合法,因为这样可以尽最大可能满足合法括号定义,因此如果这个括号为‘)’时序列也合法,那么一定是多解,输出“NO”。

那么我们如何判断括号为‘)’时也合法呢?

我们只需要将前面的(L/2-a)个问号赋值成‘(’,并且把剩下的括号赋值成‘)’,然后我们交换最后一个通过‘?’转换成的左括号以及第一个通过‘?’转换成的右括号的位置,判断序列是否合法即可,如果合法,说明有多解,不然就是唯一解。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define T()\
	int tt; \
	cin>>tt; \
	while(tt--)
#define endl "\n"
const int N=2e6+10;
int main()
{
    T()
    {
        string s;
        cin>>s;
        int now=0;
        for(int i=0;i<s.size();i++)
        {
            if(s[i]=='(')now++;//先计算序列中原有的左括号数量
        }
        if(now==s.size()/2)
        {
            cout<<"YES"<<endl;//如果左括号数量已经满足等于L/2,那么直接输出YES
            continue;
        }
        int res=s.size()/2-now;//计算缺少的左括号数量
        vector<int>pos;
        for(int i=0;i<s.size();i++)
        {
            if(s[i]=='?')
            {
                pos.push_back(i);//记录 ' ? ' 的位置
                if(now==s.size()/2)s[i]=')';
				//如果原有的加上添加过的左括号数量已经达到L/2,那就赋值为右括号
                else now++,s[i]='(';
				//不然赋值成左括号
            }
        }
        if(res==(int)pos.size())//如果增加的左括号数量恰好等于 '?' 的数量,那就唯一解
        {
            cout<<"YES"<<endl;
            continue;
        }
        swap(s[pos[res-1]],s[pos[res]]);
		//交换最后一个通过 '?' 转换成的左括号以及第一个通过 '?' 转换成的右括号
        now=0;
        bool f=0;
        for(int i=0;i<s.size();i++)
        {
            if(s[i]=='(')now++;
            else now--;
            if(now<0)
            {
                f=1;break;
            }
        }//判断交换后的序列是否满足合法括号定义
        if(f)cout<<"YES"<<endl;
        else cout<<"NO"<<endl; 
    }
}

D:

题目:

给定一个n行m列的地图,接下来给定m个数,对于1<=i<=m,hi表示第m列的前hi行格子被堵塞,不能通过,即(1,m)~(hi,m)这hi个格子不能通过。

现给定Q次询问,每次询问给定一个起始坐标(qx,qy)以及终止坐标(zx,zy)以及一个k,

一个机器人从起始坐标出发前往终止坐标,可以走任意次,每次走的格子数量规定为k,并且是朝着同一个方向走k步,规定机器人不能走到地图外面,也不能通过被堵塞的格子,问能否到达目的地。(给定的起始坐标以及终止坐标没有被堵塞)

数据范围:1<=n<=1e9,1<=m<=2e5,0<=hi<=n,1<=Q<=2e5

思路:

通过线段树维护一个区间最大值(当然,ST表也行),我们可以让机器人每次都先走到当前列的尽可能靠后的一行(假设是sj),然后走到终止坐标的列,然后前往终止坐标的行,只要起始坐标的列到终止目标的列之间没有被堵塞即可到达,所以我们查询这段区间的最值,然后和sj比较即可,需要注意的是,由于题目中规定每次走的格子数量必须为k,所以有:

abs(qx-zx)%k==0&&abs(qy-zy)==0 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define T()\
	int tt; \
	cin>>tt; \
	while(tt--)
#define endl "\n"
const int N=2e6+10;
ll a[N];
struct node
{
    ll l,r,val;
}tr[N<<2];
void build(int now,int l,int r)//建树
{
    tr[now].l=l,tr[now].r=r;
    if(l==r)
    {
        tr[now].val=a[l];
        return;
    }
    int mid=l+r>>1;
    build(now<<1,l,mid);
    build(now<<1|1,mid+1,r);
    tr[now].val=max(tr[now<<1].val,tr[now<<1|1].val);
}
ll query(int now,int l,int r,int L,int R)//询问
{
    if(L<=l&&r<=R)return tr[now].val;
    ll ans=0;
    int mid=l+r>>1;
    if(mid>=L)ans=max(ans,query(now<<1,l,mid,L,R));
    if(mid<R)ans=max(ans,query(now<<1|1,mid+1,r,L,R));
    return ans;
}
int main()
{
	#ifdef LOCAL
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	#endif
    // T()
    {
        ll n,m;
        scanf("%lld%lld",&n,&m);//注意读入用scanf,用cin会TLE
        for(int i=1;i<=m;i++)scanf("%lld",a+i);
        build(1,1,m);//建树
        int Q;
        scanf("%d",&Q);
        while(Q--)
        {
            ll qx,qy,zx,zy,k;
            scanf("%lld%lld%lld%lld%lld",&qx,&qy,&zx,&zy,&k);
            if(qy>zy)//保证起始坐标的列在终止坐标的列的前面
            {
                swap(qx,zx);
                swap(qy,zy);
            }
            if(abs(zx-qx)%k!=0||abs(zy-qy)%k!=0)
            {
                puts("NO");
                continue;
            }
            ll sj=qx+(n-qx)/k*k;//计算sj
            ll zz=query(1,1,m,qy,zy);//查询区间[qy,zy]的最大值
            if(zz>=sj)
            {
                puts("NO");
                continue;
            }
            else puts("YES");
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值