Codeforces Round #550 (Div. 3) A,B,C,D,E,F,G

Codeforces Round #550 (Div. 3) A,B,C,D,E,F,G

前言

div3一时爽,一直div3一直爽。ak一时爽,一直ak一直爽。
这大概是打的最爽的一把cf了,虽然沾了div3和题目难度的光,但是offical rank 41 大概也是我能达到的巅峰了orz,场上6题,赛后补了G,1596->1740 .
但是这场比赛还是存在的一些问题的,其中最主要的就是A题的题意没有读懂的,导致队友过B了我还没有出A,后来完全推倒重来才在 14min 的时候勉强过A,中期表现其实还可以,后期也还算稳得住了吧,但是和真的大佬还是有差距orz,21min 过B,27min 过C,43min 1WA 过D,69min 1WA过E,86min 过F。

A. Diverse Strings

题意
给定一个字符串,判断其是否连续且不重
做法
排序,逐位比较
代码

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
char a[105];
int cnt[26];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%s",a);
        sort(a,a+strlen(a));
        bool judge = true;
        for(int i=1;i<strlen(a);i++)
        {
            if(a[i]-a[i-1]!=1)
            {
                judge = false;
            }
        }
        if(judge) printf("Yes\n");
        else printf("No\n");
    }
}

B. Parity Alternated Deletions

题意
依次删去奇偶或偶奇直到不能再删去,问最后得到的数的和的最小值
做法
对奇偶分别计数,且排序,再对(大-小-1)求和
代码

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
int a[3000];
int odd[3000];
int even[3000];
int main()
{
    int n;
    scanf("%d",&n);
    int cntodd = 0;
    int cnteven = 0;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]%2==1)
        {
            odd[cntodd++] = a[i];
        }
        else
        {
            even[cnteven++] = a[i];
        }
    }
    sort(odd,odd+cntodd);
    sort(even,even+cnteven);
    int ans = 0;
    if(cntodd>cnteven)
    {
        for(int i=0;i<cntodd-cnteven-1;i++)
        {
            ans+=odd[i];
        }
    }
    else
    {
        for(int i=0;i<cnteven-cntodd-1;i++)
        {
            ans+=even[i];
        }
    }
    printf("%d\n",ans);
}


C. Two Shuffled Sequences

题意
给定一组数据将其拆分为严格单调增和严格单调减的两个序列
做法
统计数量,大于2直接判错,先输出一组等于2的,然后在输出大于0的(依次)
代码

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
int a[200010];
int cnt[200010];
int main()
{
    int n;
    int cntt = 0;
    bool judge = true;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        cnt[a[i]]++;
        if(cnt[a[i]]==2) cntt++;
        if(cnt[a[i]]==3) judge = false;
    }
    if(!judge) printf("No\n");
    else
    {
        printf("Yes\n");
        printf("%d\n",cntt);
        for(int i=0;i<200010;i++)
        {
            if(cnt[i]==2)
                printf("%d ",i);
        }
        printf("\n%d\n",n-cntt);
        for(int i=200010;i>=0;i--)
        {
            if(cnt[i]>0)
                printf("%d ",i);
        }printf("\n");
    }
}


D. Equalize Them All

题意
经过最少次题示操作使得所有数相同
做法
不难发现,1操作可使得小数等于大数,2操作可使得大数等于小数
统计出现最多的数的个数,并记录其中一个位置,从该位置分别向前和向后遍历,对每一个不等于该数的数执行一次操作
代码

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
int a[200010];
int cnt[200010];
int main()
{
    int n;
    scanf("%d",&n);
    int maxnum = 0;
    int maxn = 0;
    int sign = 0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        cnt[a[i]]++;
        if(cnt[a[i]]>maxn)
        {
            maxn = cnt[a[i]];
            maxnum = a[i];
            sign = i;
        }
    }
    printf("%d\n",n-maxn);
    for(int i=sign-1;i>0;i--)
    {
        if(a[i]==maxnum)
        {
            continue;
        }
        else if(a[i]<maxnum)
        {
            printf("%d %d %d\n",1,i,i+1);
        }
        else
        {
            printf("%d %d %d\n",2,i,i+1);
        }
    }
    for(int i=sign+1;i<=n;i++)
    {
        if(a[i]==maxnum)
        {
            continue;
        }
        else if(a[i]>maxnum)
        {
            printf("%d %d %d\n",2,i,i-1);
        }
        else
        {
            printf("%d %d %d\n",1,i,i-1);
        }
    }
}


E. Median String

题意
给定两个串,求其中位串(中位串指字典序排列后的中间值)
做法
26进制高精度,分别执行一次加法和除法
代码

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
char a[200010];
char b[200010];
int c[300010];
int d[300010];
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",a);
    scanf("%s",b);
    for(int i=0;i<n;i++)
    {
        c[i] += a[n-1-i]+b[n-1-i]-'a'-'a';
        if(c[i]>=26)
        {
            c[i]-=26;
            c[i+1]++;
        }
    }
    int tmp = 0;
    for(int i=n;i>=0;i--)
    {
        d[i] =(c[i]+tmp)/2;
        if(c[i]%2==0)
        {
            tmp=0;
        }
        else
        {
            tmp=26;
        }
    }
    for(int i=n-1;i>=0;i--)
    {
        printf("%c",d[i]+'a');
    }
}




F. Graph Without Long Directed Paths

题意
给无向图的边添加方向,使得图中不存在长度为二的路径
做法
每一个点只有源点或汇点两种,所以,假定一个点的种类,暴力dfs即可
代码

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
struct node
{
    int u,v;
}edge[200010];
vector <int> a[200010];
int num[2000010];

bool dfs(int c,int p)
{
    num[c] = p;
    bool judge = true;
    for(int i=0;i<a[c].size();i++)
    {
        if(num[a[c][i]]==-1)
        {
            if(!dfs(a[c][i],1-p))
            {
                judge = false;
            }
        }
        else
        {
            if(num[a[c][i]]!=1-p) judge = false;
        }
    }
    return judge;
}

int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    memset(num,-1,sizeof(num));
    for(int i=0;i<k;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        edge[i].u=x;
        edge[i].v=y;
        a[x].push_back(y);
        a[y].push_back(x);
    }
    if(dfs(1,0))
    {
        printf("Yes\n");
        for(int i=0;i<k;i++)
        {
            printf("%d",num[edge[i].u]);
        }
        printf("\n");
    }
    else
    {
        printf("No\n");
 }

}





G. Two Merged Sequences

题意
给定一串数字,将其不改变先后位置地分为两串,一串严格单调增,一串严格单调减
做法
如果满足要求,则每一个数必然属于下降或上升两个序列之一,对于每一个数,将它同时放在上升和下降序列的末位,若不满足条件,且另一序列中也存在该数,则将该数从序列中删去,若仍不满足,则不成立。
PS:对于两个插入,删去操作只执行一次,易证
代码

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
int a[200010];
int ans[200010];
int shangsheng[200010];
int vis1[2000010];
int xiajiang[200010];
int vis2[200010];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        scanf("%d",&a[i]);
    }
    int cntshang = 0;
    int cntxia = 0;
    bool judge = true;
    for(int i=0; i<n; i++)
    {
        if(a[i]>a[shangsheng[cntshang-1]]||cntshang==0)
        {
            shangsheng[cntshang++] = i;
            vis1[i]++;
        }
        else if(vis2[shangsheng[cntshang-1]]==1)
        {
            int tmp = shangsheng[cntshang-1];
            vis1[tmp]--;
            cntshang--;
            if(a[i]>a[shangsheng[cntshang-1]]||cntshang==0)
            {
                shangsheng[cntshang++] = i;
                vis1[i]++;
            }
        }
        if(a[i]<a[xiajiang[cntxia-1]]||cntxia==0)
        {
            xiajiang[cntxia++] = i;
            vis2[i]++;
        }
        else if(vis1[xiajiang[cntxia-1]]==1)
        {
            int tmp = xiajiang[cntxia-1];
            vis2[tmp]--;
            cntxia--;
            if(a[i]<a[xiajiang[cntxia-1]]||cntxia==0)
            {
                xiajiang[cntxia++] = i;
                vis2[i]++;
            }
        }
        if(!vis1[i]&&!vis2[i])
        {
            judge = false;
        }

    if(!judge)
    {
        printf("NO\n");
        return 0;
    }
    else
    {
        printf("YES\n");
        for(int i=0; i<cntxia; i++)
        {
            ans[xiajiang[i]] = 1;
        }
        for(int i=0; i<n; i++)
        {
            printf("%d ",ans[i]);
        }
        printf("\n");
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值