第七次训练:Educational Codeforces Round 91 (Rated for Div. 2)

1.Educational Codeforces Round 91 (Rated for Div. 2) A
在这里插入图片描述
题意:给定一个数组。问能不能找到三个递增下标,值第二个比另两个大。
  说是水题,但我提交了不只一次。因为有个细节想的一样,写出来写成了另一个样。

#include<iostream>
#include<iomanip>
#include<fstream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<cstdio>
#include<map>
#include<vector>
#include<ostream>
#include<istream>
typedef long long ll;
using namespace std;
#define mod 1e9+7
#define PI acos(-1.0)
const int maxn=2*1e5;
const int mx=(1<<20)+99;
ll n,a[1100],b[5],ans,flag1,flag2;
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
    int t;
    cin>>t;
    for(int o=1;o<=t;o++)
    {
        cin>>n;
        flag1=flag2=0;
        int j=0;
        for(int i=1;i<=n;i++)
        cin>>a[i];
        for(int i=2;i<=n;i++)
        {
            if(a[i]>a[i-1]&&!flag1) { flag1=1; b[j++]=i-1;  }
            if(flag1&&a[i]<a[i-1]) { flag2=1; b[j++]=i-1; b[j]=i; break; }
        }
        if(!flag2)
        cout<<"NO";
        else
        {
            cout<<"YES"<<endl;
            for(int i=0;i<=2;i++)
            cout<<b[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

2.Educational Codeforces Round 91 (Rated for Div. 2) B
在这里插入图片描述在这里插入图片描述
题意:给定一个机器会用的猜拳表,但不一定从哪开始(到了最后一个接下来返回第一个)。求另一个表,表示你会出的可能,猜拳时你会从第一个开始出。要使得机器从各个位置开始你能够赢得的局数平均值最大(机器可能选择各种起始点,但你的顺序不能变)。
  其实只出一种就能解决问题,因为你出的任意一个都会和机器出的任意一个比,所以只要每一个和所有的比都能够获胜最多就好了。昨晚做题时想着自己和机器的都会变,所以判断的时候可能会有很多情况,还只是单个决定胜负。结束后认真看了下题就明白怎么做了。

#include<iostream>
#include<iomanip>
#include<fstream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<cstdio>
#include<map>
#include<vector>
#include<ostream>
#include<istream>
typedef long long ll;
using namespace std;
#define mod 1e9+7
#define PI acos(-1.0)
const int maxn=2*1e5;
const int mx=(1<<20)+99;
ll n,aans,b[4];
char ans,a[maxn+10];
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
    int t;
    cin>>t;
    for(int o=1;o<=t;o++)
    {
        cin>>a;
        n=strlen(a);
        b[1]=b[2]=b[3]=0;
        for(int i=0;i<n;i++)
        {
            if(a[i]=='R') b[3]++;
            if(a[i]=='S') b[1]++;
            if(a[i]=='P') b[2]++;
        }
        aans=1; ans='R';
        if(b[2]>b[aans]) { aans=2; ans='S'; }
        if(b[3]>b[aans]) ans='P';
        for(int i=1;i<=n;i++)
        cout<<ans;
        cout<<endl;
    }
    return 0;
}

3.Educational Codeforces Round 91 (Rated for Div. 2) C
在这里插入图片描述
题意:有n个学生的能力ai。对他们分组,使得每组能力最小的人的能力乘以组员数不小于某个值k,可能有人不分组。求最多的组数。
  这个题目即使没学过贪心也会做。只要单个大于等于k自己一组,剩下的从大到小能成组就成。不过,我也没一次性过。

#include<iostream>
#include<iomanip>
#include<fstream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<cstdio>
#include<map>
#include<vector>
#include<ostream>
#include<istream>
typedef long long ll;
using namespace std;
#define mod 1e9+7
#define PI acos(-1.0)
const int maxn=2*1e5;
const int mx=(1<<20)+99;
ll n,aans,b[4];
char ans,a[maxn+10];
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
    int t;
    cin>>t;
    for(int o=1;o<=t;o++)
    {
        cin>>a;
        n=strlen(a);
        b[1]=b[2]=b[3]=0;
        for(int i=0;i<n;i++)
        {
            if(a[i]=='R') b[3]++;
            if(a[i]=='S') b[1]++;
            if(a[i]=='P') b[2]++;
        }
        aans=1; ans='R';
        if(b[2]>b[aans]) { aans=2; ans='S'; }
        if(b[3]>b[aans]) ans='P';
        for(int i=1;i<=n;i++)
        cout<<ans;
        cout<<endl;
    }
    return 0;
}

4.Educational Codeforces Round 91 (Rated for Div. 2) D
在这里插入图片描述在这里插入图片描述
题意:你有n个力量为ai的战士,你想让他们剩下其中m个力量为bj的战士(顺序不能变)。你可以用消耗x法术的火球术技能,那会连续消失K个 战士,或者放消耗y法术的狂暴技能,那样会选定两个战士并淘汰掉力小的那个。求需要消耗最小的法术值。
  这个题目乍看上去挺麻烦的,但当把这些要留下的战士位置记录下来后就发现(如果位置和原来不一样就得-1),需要去掉的就是一段一段的了,然后就是决定这些小段怎么去掉了。对于每一小段,如果小于k,只能用二技能,只看能不能用就可以了(不能就得-1了).而如果不小于k,那么可能全部用二技能,也可能用一个一技能然后全部二技能,还可能用尽可能多的一技能最后补齐二技能,取最小值即可(后来两种情况两个技能都是必定能用的,因为这段数字必定有大小之分,第一种情况还得和小于k时一样)。当然,对于每段还要注意是不是边缘(包含第一个或最后一个元素)子段,分情况视之。代码就直来直去,所以看起来很繁琐。

#include<iostream>
#include<iomanip>
#include<fstream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<cstdio>
#include<map>
#include<vector>
#include<ostream>
#include<istream>
typedef long long ll;
using namespace std;
#define mod 1e9+7
#define PI acos(-1.0)
const int maxn=2*1e5;
const int mx=(1<<20)+99;
ll n,m,x,s,y,a[maxn+10],aans,ans,flag;
struct lll{
    ll num,pos;
} b[maxn+10];
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
    int t;
    //cin>>t;
    //for(int o=1;o<=t;o++)
    //{
        cin>>n>>m;
        cin>>x>>s>>y;
        for(int i=1;i<=n;i++)
        cin>>a[i];
        flag=0;
        for(int i=1,j=1;j<=m;j++)
        {
            cin>>b[j].num;
            if(i>n) flag=1;
            if(!flag)
            for(;i<=n;)
            {
                if(a[i]==b[j].num) { b[j].pos=i; i++; break; }
                if(i==n) flag=1;
                i++;
            }
        }
        /*for(int i=1;i<=n;i++)
        cout<<a[i]<<" ";
        cout<<endl;
        for(int i=1;i<=m;i++)
        cout<<b[i].pos<<" ";
        cout<<endl;*/
        if(flag) { cout<<"-1"<<endl; return 0; }
        ans=0;
        for(int i=1,j=1,k;i<=m+1;i++)
        {
            if(i==m+1) k=n; else k=b[i].pos-1;
            if(i!=1) j=b[i-1].pos+1;
            //cout<<j<<" "<<k<<endl;
            if(k<j) continue;
 
            aans=-1;
            for(int h=j;h<=k;h++)
            aans=max(aans,a[h]);
 
            if(k-j+1>=s)
            {
                ll ss;
                ss=min(((k-j+1)%s)*y+((k-j+1)/s)*x,x+(k-j+1-s)*y);
                if(i==1)
                {
                    if(b[1].num>aans)
                    ss=min((k-j+1)*y,ss);
                }
                else if(i==m+1)
                {
                    if(b[m].num>aans)
                    ss=min((k-j+1)*y,ss);
                }
                else
                {
                    if(b[i-1].num>aans||b[i].num>aans)
                    ss=min((k-j+1)*y,ss);
                }
                ans+=ss;
                continue;
            }
 
            if(i==1)
            {
                if(b[1].num<aans)
                flag=1;
                else ans+=((k-j+1)%s)*y;
            }
            else if(i==m+1)
            {
                if(b[m].num<aans)
                flag=1;
                else ans+=((k-j+1)%s)*y;
            }
            else
            {
                if(b[i-1].num<aans&&b[i].num<aans)
                flag=1;
                else ans+=((k-j+1)%s)*y;
            }
            if(flag) break;
        }
        if(flag) cout<<"-1"<<endl;
        else cout<<ans<<endl;
    //}
    return 0;
}

总结:这一次也没全整理,因为后面的怎么也没写出来,起码这四个都是自己写的。其中A是昨晚做ac的,剩下的今天或改或做的,昨晚做题时没想到B题这么简单,以为会很麻烦的。当然,这次D题我没看任何题解,完全自己ac的,在之前的话我都是先看看人家的想法,再看自己是不是能修改别人的方法或者由人家的想法引申出另一种方法,而这次第一眼看到还是没思路,但尝试再纸上画画草图并做一些小演算终于自己找出来了做法,这就是进步吧,说明第一周的训练还是有效果的。我看了官方题解,说真的,题解的英文看着真是吃力,查了单词有些句子也不明白啥意思,直接成句翻译更看不懂,所以,我也不知道我的做法和人家的一样不一样。我补题的时候更喜欢在cf上提交,因为cf上可以看到题目的部分测例,有时可以通过错误测例找到错在哪,方便找到程序中的不足和错误,明白自己写代码时会出错在哪些方面。我也不知道这样好不好,但我确实发现我经常忽略的一些小点虽然每个程序都不一样,但在某种方面上或者说类型有相似,如果克服这个,代码实现速度 会大大提升的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值