Codeforces Round #776 (Div. 3) 总结

感想

这场比赛还是暴露了自己的许多问题,第二题因为边界没写好导致wa了半小时,所以做题的时候不能想当然,要自己想一下为什么。还有一个非常重要的地方就是要跳出固定思维模式,这是我感悟比较深的,div3如果是按照题目描述呢样想,是相当的复杂,但是仔细想一下,只要排一下序,只要前2*n个点,呢么一定可以构造出满足条件的答案。没想到在实现c题的时候,也出现了较大的失误,已经弹出了,vector的长度已经变了,怎么还可以用呢!!!

A题

A题比较好像,只要子串的左边有偶数个,右边也有偶数个就行

#include <bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=1e6;
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        string s;
        char c;
        cin>>s>>c;
        int l,r;
        bool flag=false;
        for(int i=0;s[i];i++)
        {
            if(s[i]==c)
            {
                l=i;
                r=s.size()-1-i;
                if(l%2==0&&r%2==0)
                {
                    flag=true;
                    break;
                }
            }
        }
        if(flag) puts("Yes");
        else puts("No");
    }
    return 0;
}

B题

可以想一下,我们可以尽量让x%a==a-1,然后再次基础上让x/a尽可能的大,因为x每增加a,才会让x/a加1,但是x每增加1我们可以让x%a加1,所以我们肯定是从大到小枚举,第一个满足x%a==a-1的,一定是最大的,但是这样会超时,我们发现,如果r%a==c,呢么r-(c+1) %a==a-1,这里需要特判一下,因为此时r-(a+1)有可能不在范围内,即小于l,这时候其实完全没有必要让余数凑成a-1了,因为凑不到a-1!而且还会让x/a和x%a都变小,所以此时的答案就是r/a+r%a。

#include <bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=1e6;
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        ll l,r,a;
        cin>>l>>r>>a;
        ll d=r%a;
        if(d==a-1) cout<<r/a+d<<endl;
        else
        {
            ll x=r-(d+1);
            if(x>=l) cout<<(r-(d+1))/a+a-1<<endl;
            else cout<<r/a+r%a<<endl;
        }
    }
    return 0;
}

C题

看着很难想,其实就是贪心+排序。一定要跳出思维模式!!!

#include <bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=1e6;
struct node{
    int x,v,id;
};
bool cmp1(node x,node y) {return x.v<y.v;}
bool cmp2(node x,node y) {return x.x<y.x;}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n,m;
        cin>>n>>m;
        vector<node>v;
        for(int i=1;i<=m;i++)
        {
            int a,b;
            cin>>a>>b;
            v.push_back({a,b,i});
        }
        ll sum=0;
        sort(v.begin(),v.end(),cmp1);
        int len=v.size();
        for(int i=0;i<len;i++)
        {
            if(i<2*n) sum+=v[i].v;
            else v.pop_back();
        }
        cout<<sum<<endl;
        sort(v.begin(),v.end(),cmp2);
        for(int i=0,j=v.size()-1;i<j;i++,j--)
        {
            cout<<v[i].id<<" "<<v[j].id<<endl;
        }
        cout<<endl;
    }
    return 0;
}

D题

很好的一道模拟题,锻炼了模能力,凡是和模有关的,最好是从0~n-1 ,因为这样才方便进行模运算。

我们逆向推理一下,发现第n为一定是最后一次操作得来的,因为前n-1次操作,不会让第n未发生变化,所以我们要看最后一位进行了几次变化,从而推理出上一步的数组是什么样子的,这样类推就行。不得不说,这有点补码那意思了,把减法变成加法。

#include <bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=2e3+100;
int a[N],b[N],mp[N],ans[N];
int n;
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
            mp[a[i]]=i;
        }
        for(int i=n;i>=1;i--)
        {
            int cnt;
            int x=i-1,y=mp[i];
            //计算需要走多少步
            if(x<y) cnt=y-x;
            else if(x>y) cnt=(i-1-x)+y+1;
            else cnt=0;
            ans[i]=cnt;
            
            for(int j=0;j<n;j++) b[j]=a[j];
            for(int j=0;j<i;j++)
            {
                a[(j-cnt+i)%i]=b[j];
            }
            for(int j=0;j<i;j++) mp[a[j]]=j;
        }
        for(int i=1;i<=n;i++)
        {
            cout<<ans[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值