Educational Codeforces Round 151 (Rated for Div. 2)

A. Forbidden Integer

题意:输入给出整数n,k,x,要求用任意数量的1-k中的数组成n,其中1-k中不能选择x

思路:其实就是分情况讨论,当x不为1的时候,则可以用n个1直接组成n,当x为1时再讨论k,如果k为1则无解,如果k为2,则只能用2,所以只能组合出偶数,如果k>=3,通过尝试枚举可以发现任何一个>1的数都可以仅有2和3来组成,如果为偶数则可以直接全用2,如果为奇数,则可以用一个3,剩余为偶数全2

ac代码:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define INF 0x3f3f3f3f
#define pb push_back
#define int long long
#define Mirai ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef pair<int,int> pii;
const int N=1e6+10;
int n,k,x;
void solve()
{
    cin>>n>>k>>x;
    if(x!=1)
    {
        cout<<"YES"<<endl;
        cout<<n<<endl;
        for(int i=0;i<n;i++)cout<<1<<" ";
        cout<<endl;
    }
    else 
    {
        if(k==1)cout<<"NO"<<endl;
        else if(k==2)
        {
            if(n%2==0)
            {
                cout<<"YES"<<endl;
                cout<<n/2<<endl;
                for(int i=0;i<n/2;i++)cout<<2<<" ";
                cout<<endl;
            }
            else cout<<"NO"<<endl;
        }
        else 
        {
            if(n==1)cout<<"NO"<<endl;
            else 
            {
                cout<<"YES"<<endl;
                if(n%2==0)
                {
                    cout<<n/2<<endl;
                    for(int i=0;i<n/2;i++)cout<<2<<" ";
                    cout<<endl;
                }
                else
                {
                    cout<<(n-3)/2+1<<endl;
                    cout<<3<<" ";
                    n-=3;
                    for(int i=0;i<n/2;i++)cout<<2<<" ";
                    cout<<endl;
                }
            }
        }
    }
}
signed main()
{
    Mirai;
    int T=1;
    cin>>T;
    while(T--)
    {
        solve();
    }
}

B. Come Together

题意:输入给出一个起点的坐标以及两个终点的坐标,要求输出起点到两个终点的最小路径中的最大重合路径

思路:通过观察可以发现答案为起点到两个终点的曼哈顿距离之和减去两个终点的曼哈顿距离

ac代码:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define INF 0x3f3f3f3f
#define pb push_back
#define int long long
#define Mirai ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef pair<int,int> pii;
const int N=1e6+10;
struct Node
{
    int x,y;
}p[3];
int dist(Node a,Node b)
{
    return abs(a.x-b.x)+abs(a.y-b.y)+1;
}
void solve()
{
    for(int i=1;i<=3;i++)cin>>p[i].x>>p[i].y;
    cout<<(dist(p[1],p[2])+dist(p[1],p[3])-dist(p[2],p[3])+1)/2<<endl;
}
signed main()
{
    Mirai;
    int T=1;
    cin>>T;
    while(T--)
    {
        solve();
    }
}

C. Strong Password

题意:输入给出字符串s,密码长度m以及密码上下限字符串l和r,要求找出一个长度为m的字符串,要求字符串不能为s的一个子序列,并且对于字符串的每一位,必须大于等于对应位置上的l和小于等于对应位置上的r

思路:由于密码最大只有10位,而每一位上的密码最多只有10种情况,所以可以枚举每一位密码然后到字符串中去对应寻找,我们在搜索某一位字符串时如果有一种情况没有搜索到就说明找到了合法情况,直接输出YES并返回即可,如果所有情况都搜到了,接下来进行下一位的密码搜索的时候只需要从当前位搜索到的最后一位的下一位开始搜索即可,具体原因见代码注释,只选择末尾位置的密码字符,保证了时间复杂度,每个位置上的密码只会向后延申一个分支,而不会每个选择都要对应之后搜索一遍

ac代码:


#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<unordered_map>
#include<queue>
#include<stack>
#include<string>
#define inf 0x3f3f3f3f
#define PII pair<int,int>
#define fi first
#define se second
#define ll long long
using namespace std;
//本题的重点在于找到一个密码串在s中不存在,而不是寻找存在的字符串,要注意理解这一点
//在搜完某一位密码之后,在进行后续搜索的时候,末尾位置的搜索区域最小
//并且这些搜索区域其他的位置的搜索区域也可以覆盖到,也就是说我们选取末尾位置的字符
//作为当前搜完的密码位上的字符,搜不到密码的概率最大,并且这样搜出的所有后续情况都是前面其他位置可以覆盖到的
//其他位上的密码字符进行后续搜索对于末尾位置的后续搜索是一个包含关系,情况只多不少
void solve()
{
    int m;
    string s,l,r;
    cin >>s>>m>>l>>r;
    int cur=0;
    for(int i=0;i<m;i++)
    {
        int res=0;
        for(char j=l[i];j<=r[i];j++)
        {
            int tem=s.find(j,cur);
            if(tem==-1)
            {
                cout <<"YES"<<endl;return ;
            }
            tem++;
            res=max(tem,res);
        }
        cur=res;
    }
    cout <<"NO"<<endl;
}
int main(){
    int t = 1;
    cin >>t;
    while(t--)
    {
        solve();
    }
    return 0;
}

D. Rating System

题意:题目给出n个数字,要求以0开始,从左到右一直加到数组末尾,数组中存在负数,而此时可以设置一个整数k,当累计分数>=k之后,则分数最低为k,也就是说如果在减一个数之后即将<k时,则最多减到k,

思路:不难发现,这个数字k应该是一个在加上一个正数后即将加上一个负数的时候设置为当前分数值,也就是一个末尾为正数并且之后的第一个数为负数的前缀和,而在哪个边界加上k是接下来要思考的问题,设置的k要尽可能抵消掉多的减分,而不一定设置在第一个负数前,因为该负数后可能有数个正数导致这些正数之后的减分的不会被抵消,所以应该思考哪一个区间造成的减分最多,而在这个区间前设置k,注意此处不是寻找全负区间,而是总和为负数并且总和最小的区间,然后此区间前的数组前缀和即为答案

ac代码:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define INF 0x3f3f3f3f
#define pb push_back
#define int long long
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define Mirai ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef pair<int,int> pii;
const int N=1e6+10;
int n;
int a[N],b[N];
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i],b[i]=b[i-1]+a[i];
    int res=0,premax=0,now=0;
	//res为最后结果 premax用来实时记录以当前位置结尾的最大前缀和 now用来记录得到的最小区间和
	//这里同寻找最大区间异或和比较相同,对于以某一点结尾的前缀和减去在此之前的所有前缀和
	//就可以得到从开头到当前点结尾的所有区间和,而我们要找最小区间和,并不关心是那一部分的区间和
	//所以只需要记录一个最大的前缀和,然后直接相减就可以得到一个最小区间和
    for(int i=1;i<=n;i++)
    {
        if(b[i]-premax<now)
        {
            now=b[i]-premax;
            res=premax;
        }
        premax=max(premax,b[i]);
    }
    cout<<res<<endl;
}
signed main()
{
    Mirai;
    int T=1;
    cin>>T;
    while(T--)
    {
        solve();
    }
}

  • 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、付费专栏及课程。

余额充值