Codeforces Global Round 11 ABCD题解

真阴间啊 , 不仅时长阴间, 题目也有点emmmmm
打的不顺利,没有按预想在15分钟内把AB题写出来 ((。・∀・)ノ゙害)
开局码了发A WA2 人傻了 开始质疑自己了 先搁着吧
然后又码了一个半成品B emmm 有bug 又鸽着了
然后C好像没啥想法 鸽着 看看D
如果没有翻译我估计D题我是写不出来的 QAQ 简直阅读理解

1427A题链接
给你一个数组 要我们重新排列以后 对于任意长度的前缀和不为0
那么考虑长度为n的前缀和 ,如果它为0 那么必然不可行 输出NO
否则根据前缀和的大小 考虑是从大到小输出 还是从小到大输出
非常简单 (然后我当时不知道在讨论啥玩意 WA2)

 #include<bits/stdc++.h>
#include<stdlib.h>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<time.h>
#include <cstdio>
#include <iostream>
#include <vector>
#define ll long long
#define int long long
#define inf 0x3f3f3f3f
#define mods 1000000007
#define modd 998244353
#define PI acos(-1)
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
#define si size()
#define E exp(1.0)
#define fixed cout.setf(ios::fixed)
#define fixeds(x) setprecision(x)
#define IOS ios::sync_with_stdio(false);cin.tie(0)
 using namespace std;
 ll gcd(ll a,ll b){
    
    if(a<0)a=-a;if(b<0)b=-b;return b==0?a:gcd(b,a%b);}
template<typename T>void read(T &res){
    
    bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
for(res=ch-48;isdigit(ch=getchar());res=(res<<1)+(res<<3)+ch - 48);flag&&(res=-res);}
ll lcm(ll a,ll b){
    
    return a*b/gcd(a,b);}
ll qp(ll a,ll b,ll mod){
    
    ll ans=1;if(b==0){
    
    return ans%mod;}while(b){
    
    if(b%2==1){
    
    b--;ans=ans*a%mod;}a=a*a%mod;b=b/2;}return ans%mod;}//快速幂%
ll qpn(ll a,ll b, ll p){
    
    ll ans = 1;a%=p;while(b){
    
    if(b&1){
    
    ans = (ans*a)%p;--b;}a =(a*a)%p;b >>= 1;}return ans%p;}//逆元   (分子*qp(分母,mod-2,mod))%mod;

const int ma=1;
ll a[200];
ll b[200];
signed main(){
    
    
ll t;
read(t);
while(t--){
    
    
ll n;
read(n);
ll la=0;
ll lb=0;
ll add=0;
ll f=0;
for(int i=1;i<=n;i++){
    
    
read(a[i]);
add=add+a[i];//if(x>=0){
    
    

}
if(add==0){
    
    
    printf("NO\n");
    continue;
}
 sort(a+1,a+1+n);
 if(add>0){
    
    
        printf("YES\n");
    for(int i=n;i>=1;i--){
    
    
        printf("%lld ",a[i]);
    }
 }
 else{
    
    
       printf("YES\n");
    for(int i=1;i<=n;i++){
    
    
        printf("%lld ",a[i]);
    }

 }
printf("\n");
}
}

1427B链接
给一个长度为n的字符串 包含L W代表输赢
输了没有积分, 单赢拿一分,连续赢(前一个是W 后一个也是W) 拿两分
给了我们操作数 K 可以更改 字符串 询问最终可以拿最多 多少分

观察一下WLW WLLW LLW WLL
不难不发 如果能填充W之间的缝隙 显然贡献值是最高的
那么我们要分类处理
先找到第一个W的pos 和最后一个W的pos 在这个区间里面找长度L的缝隙 存起来 排序 优先填充小的
如果处理完了以后还有多的K 可以使用 那么就处理1-- <pos1 以及 pos2+1 到n
思路就这样 码起来有点点麻烦

https://paste.ubuntu.com/p/v2m3FzCHFQ/      链接里面  

1247C
感觉挺像寒假训练营那个宝可梦的问题
题目给了我们一个R长度的坐标系
自己初始位置为(1, 1)
现在有n个人 在不同时间出现在不同的地点 时间过了会消失
移动速度是1s 一个单位 问最多能遇到多少个人
(说到这一步就看自己有没有寒假好好补题了)

#include<bits/stdc++.h>
#include<stdlib.h>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<time.h>
#include <cstdio>
#include <iostream>
#include <vector>
#define ll long long
#define int long long
#define inf 0x3f3f3f3f
#define mods 1000000007
#define modd 998244353
#define PI acos(-1)
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
#define si size()
#define E exp(1.0)
#define fixed cout.setf(ios::fixed)
#define fixeds(x) setprecision(x)
#define IOS ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
ll gcd(ll a,ll b)
{
    
    
    if(a<0)
        a=-a;
    if(b<0)
        b=-b;
    return b==0?a:gcd(b,a%b);
}
template<typename T>void read(T &res)
{
    
    
    bool flag=false;
    char ch;
    while(!isdigit(ch=getchar()))
        (ch=='-')&&(flag=true);
    for(res=ch-48; isdigit(ch=getchar()); res=(res<<1)+(res<<3)+ch - 48)
        ;
    flag&&(res=-res);
}
ll lcm(ll a,ll b)
{
    
    
    return a*b/gcd(a,b);
}
ll qp(ll a,ll b,ll mod)
{
    
    
    ll ans=1;    //快速幂%
    if(b==0)
    {
    
    
        return ans%mod;
    }
    while(b)
    {
    
    
        if(b%2==1)
        {
    
    
            b--;
            ans=ans*a%mod;
        }
        a=a*a%mod;
        b=b/2;
    }
    return ans%mod;
}
ll qpn(ll a,ll b, ll p)
{
    
    
    ll ans = 1;    //逆元   (分子*qp(分母,mod-2,mod))%mod;
    a%=p;
    while(b)
    {
    
    
        if(b&1)
        {
    
    
            ans = (ans*a)%p;
            --b;
        }
        a =(a*a)%p;
        b >>= 1;
    }
    return ans%p;
}
const int maxn=1e6+7;
int euler[maxn],prime[maxn],cntt;
void Euler(int n)//求n以内所有数的欧拉函数值
{
    
    
    memset(euler,0,sizeof(euler));
    euler[1]=0;
    cntt=0;
    for(int i=2; i<=n; i++)
    {
    
    
        if(!euler[i])
        {
    
    
            euler[i]=i-1;
            prime[cntt++]=i;
        }
        for(int j=0; j<cntt&&prime[j]*i<=n; j++)
        {
    
    
            if(i%prime[j])
                euler[prime[j]*i]=euler[i]*(prime[j]-1);
            else
            {
    
    
                euler[prime[j]*i]=euler[i]*prime[j];
                break;
            }
        }
    }
}

struct pe{
    
    
ll t;
ll x;
ll y;


}sb[1000006];
const int op=1e6+7;
ll pre[op],dp[op];
ll fac[op];
ll dp2[op];
bool check(ll i,ll j){
    
    
    if(abs(sb[i].x-sb[j].x)+abs(sb[i].y-sb[j].y)<=(sb[i].t-sb[j].t)){
    
    
        return true;
    }
return false;
}
signed main()
{
    
       fac[1]=1;
    ll n,r;
    read(r);
    read(n);
    for(int i=1;i<=n;i++)
    {
    
    
    read(sb[i].t);
    read(sb[i].x);
    read(sb[i].y);

    }
    sb[0].t=0;
    sb[0].x=1;
    sb[0].y=1;

    for(int i=0;i<=n;i++){
    
    
    pre[i]=-inf;
    dp[i]=-inf;
    }
    dp[0]=0;
    pre[0]=0;
    ll need=0;
    for(int i=1;i<=n;i++)
    {
    
    
        if(i>1000) dp[i]=pre[i-1001]+1;
        for(int j=max(need,i-1002);j<i;j++)
        {
    
    
            if(check(i,j)){
    
    
				dp[i]=max(dp[i],dp[j]+1);
            }
            else{
    
    
                continue;
            }
        }
        pre[i]=max(pre[i-1],dp[i]);
    }
    ll ans=0;
    ll ma=0;
    for(int i=1;i<=n;i++) {
    
    
    ans=max(ans,dp[i]);
    }
    printf("%lld\n",ans);
    return 0;
}

1427D链接
给我们一个序列 我们可以把它划分为若干个块 从左往右
然后块D_k D_(k-1) ----- D1 逆排列 但是块里面的顺序不变
问操作多少次可以使得序列变得有序 1–n排列
输出操作次数以及 每次的划分块数 和划分每个块的大小
注意到n很小 而且题目也不要求极限化操作次数
那么直接暴力划分就好了, 最坏的情况下一次划分 只能使得一个数归位
52次而已 暴力足以
举个栗子 6 5 4 3 2 1 划分1 1 4 变为 4 3 2 1 5 6
划分1 1 4 变为 2 1 5 6 3 4
划分1 1 4 变为 5 6 3 4 1 2
划分 2 2 2 变为 1 2 3 4 5 6

#include<bits/stdc++.h>
#include<stdlib.h>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<time.h>
#include <cstdio>
#include <iostream>
#include <vector>
#define ll long long
#define int long long
#define inf 0x3f3f3f3f
#define mods 1000000007
#define modd 998244353
#define PI acos(-1)
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
#define si size()
#define E exp(1.0)
#define fixed cout.setf(ios::fixed)
#define fixeds(x) setprecision(x)
#define IOS ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
ll gcd(ll a,ll b)
{
    
    
    if(a<0)
        a=-a;
    if(b<0)
        b=-b;
    return b==0?a:gcd(b,a%b);
}
template<typename T>void read(T &res)
{
    
    
    bool flag=false;
    char ch;
    while(!isdigit(ch=getchar()))
        (ch=='-')&&(flag=true);
    for(res=ch-48; isdigit(ch=getchar()); res=(res<<1)+(res<<3)+ch - 48)
        ;
    flag&&(res=-res);
}
ll lcm(ll a,ll b)
{
    
    
    return a*b/gcd(a,b);
}
ll qp(ll a,ll b,ll mod)
{
    
    
    ll ans=1;    //快速幂%
    if(b==0)
    {
    
    
        return ans%mod;
    }
    while(b)
    {
    
    
        if(b%2==1)
        {
    
    
            b--;
            ans=ans*a%mod;
        }
        a=a*a%mod;
        b=b/2;
    }
    return ans%mod;
}
ll qpn(ll a,ll b, ll p)
{
    
    
    ll ans = 1;    //逆元   (分子*qp(分母,mod-2,mod))%mod;
    a%=p;
    while(b)
    {
    
    
        if(b&1)
        {
    
    
            ans = (ans*a)%p;
            --b;
        }
        a =(a*a)%p;
        b >>= 1;
    }
    return ans%p;
}
vector<int> v[100009];
ll a[609];
ll b[609];
vector<int> ans[100009];
signed main()
{
    
    
    ll n;
    read(n);
    ll sum=0;
    ll rnm=0;
    for(int i=1; i<=n; i++)
    {
    
    
        read(a[i]);
        if(a[i]>a[i-1]){
    
    
            rnm++;
        }
    }
    ll ti=0;
    while(true)
    {
    
    
        ti++;
        ll cnt=1,p1,p;
        bool flag=0;
        //	ll pos=0;
        for(int i=2; i<=n; i++)
        {
    
    

            if(a[i-1]!=a[i]-1)
            {
    
    
                flag=1;

            }
            else{
    
    
                continue;
            }
        }
        if(!flag)
            break;
        for(int i=1; i<=n; i++)
        {
    
    
            if(a[i]!=i)
            {
    
    
                p1=i;
                break;
            }
            else{
    
    
                continue;
            }
        }
        if(p1!=1)
        {
    
    
            ans[ti].pb(p1-1);
        }
         else{
    
    
            sum++;
         }
        for(int i=p1+1; i<=n; i++)
        {
    
    
            if(a[i-1]==a[i]-1)
            {
    
    
                cnt++;
                continue;
            }
            if(a[i-1]!=a[i]-1)
            {
    
    
                p=a[p1];
                p++;
                p--;
                p1=i;
                break;

            }

        }
        ans[ti].pb(cnt);
        cnt=1;
        for(int i=p1; i<=n; i++)
        {
    
    
            if(a[i]==p-1)
            {
    
    
                p1=i;
                ans[ti].pb(cnt);
                //pos++;
                break;
            }
            cnt++;
        }
        if(p1!=n)
            ans[ti].pb(n-p1);
        int pos=n,now=1;
        for(int i=ans[ti].size()-1; i>=0; i--)
        {
    
    
            for(int j=pos-ans[ti][i]+1; j<=pos; j++)
            {
    
    
                b[now++]=a[j];
            }
            pos=pos-ans[ti][i];
        }
        for(int i=1; i<=n; i++)
        {
    
    
            a[i]=b[i];
        }

    }
    printf("%lld\n",ti-1);
    for(int i=1; i<ti; i++)
    {
    
    
        printf("%lld ",ans[i].size());
        for(int j=0; j<ans[i].size(); j++)
        {
    
    
            printf("%lld ",ans[i][j]);
        }
        printf("\n");
    }
    return 0;

}

E题不会 但是应该可以补 qwq
开局预测-174 结束的时候上到2000分了 就很刺激
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45948940/article/details/109010084