【Codeforces Round #545 (Div. 2)】 A B C D

71 篇文章 0 订阅

这场失策的地方是 当时C过的人比B多 但是自己还在肝B 使得D差几分钟就能出 D(赛后一遍过)

A

题意 1代表一种菜 2 代表另一个菜 问你偶数区间一分为二 两边各是一种菜 区间最长为

我们可以找到第一个右边不等于左边的菜进行左右枚举即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
const int MAX_N = 100025;
int arr[MAX_N],arr_[MAX_N];
stack <int > st;
int main()
{
    int n,maxx = 0;
    scanf("%d",&n);
    for(int i = 1;i<=n;++i)
        scanf("%d",&arr[i]);
    for(int i = 2;i<=n;++i)
    {
        int tmp;
        if(arr[i]!=arr[i-1])
        {
            tmp = 1;
            while(i+tmp<=n&&i-1-tmp>=1&&arr[i+tmp]==arr[i]&&arr[i-1-tmp]==arr[i-1])
            {
                tmp++;
            }
            maxx = max(maxx,tmp);
        }
    }
    //dbg(maxx);
    printf("%d\n",maxx*2);
    return 0;
}

B

B这题一开始无法上手 后来发现实际上你只要把 满足 (1,1) (1,0) (0,1) (0,0) 在一队里面出现的次数为x y z J,那么他在另一队出现的次数就是 num-x,num_-y,num__-z,num___-J;

我们容易得到下列方程 x+y+z+J = n/2   1.

x+y = num__-z+num - x -> x+y+z + x = num + num__ -> n/2- J + x = num + num__

所以我们只要枚举 x和J即可 并且要满足num_ + num___>=n/2-J-X

进行枚举即可得到答案

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
const int MAX_N = 5025;
int ans[MAX_N];
char str[MAX_N],str_[MAX_N];
vector<int > vt,vt_,vt__,vt___;
int main()
{
    int n,num = 0,num_ = 0,num__ = 0,num___ = 0,cnt = 0,x=0,y=0,z=0,J=0;
    scanf("%d",&n);
    scanf("%s",str+1);
    scanf("%s",str_+1);
    for(int i = 1;i<=n;++i)
    {
        if(str[i]=='1'&&str_[i]=='1')
        {
            vt.push_back(i);
            num++;
        }
        else if(str[i]=='1')
        {
            vt_.push_back(i);
            num_++;
        }
        else if(str_[i]=='1')
        {
            vt__.push_back(i);
            num__++;
        }
        else
        {
            vt___.push_back(i);
            num___++;
        }
    }
    //dbg2(num,num_);
    //dbg2(num__,num___);
    int flag = 0;
    int ck = num__ + num;
    //dbg(ck);
    for(int i = 0;i<=min(n/2,num);i++)
    {
        for(int k = 0;k<=min(n/2,num___)&&i+k<=n/2;k++)
        {
            if(n/2-k+i==ck&&num_+num__>=n/2-i-k)
            {
                x = i;
                J = k;
                flag = 1;
                break;
            }
        }
    }
    //dbg2(x,J);
    if(!flag)
    {
        printf("-1\n");
    }
    else
    {
        for(int i = 0;i<=min(n/2,num_)&&y+x+J<=n/2;i++)
        {
            for(int j = 0;j<=min(n/2,num__)&&x+y+J+j<=n/2;j++)
            {
                if(i+j==n/2-x-J)
                {
                    y = i;
                    z = j;
                    break;
                }
            }
        }
        for(int i = 0;i<x;++i) ans[++cnt] = vt[i];
        for(int i = 0;i<y;++i) ans[++cnt] = vt_[i];
        for(int i = 0;i<z;++i) ans[++cnt] = vt__[i];
        for(int i = 0;i<J;++i) ans[++cnt] = vt___[i];
        for(int i = 1;i<=cnt;++i)
            i==cnt?printf("%d\n",ans[i]):printf("%d ",ans[i]);
    }
    return 0;
}

C

题意 给你好多条街道 定义十字路口为街道相交的地方 问你对每一个十字路口 能重新分配的最大高度为x 满足每条街道大家的相对高度不变

做法 根据样例容易发现 其实答案就是 那个点再两条街道取的离散化后的差 加上矮的那个高度因为要调高度 所以答案为最大值加上升高的高度 于是就是统计行的最大值 r_mx ,列的最大值 c_mx,离散化后的两个数组 行离散化mp,列离散化mp_

但是发现有问题 就是 3 3

1 2 3

1 2 3

1 2 3

这组数据的问题 所以加了个特判 如果某一行或者某一列他的最大值是1 那么直接就取相对的另一个最大值

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
const int MAX_N = 1025;
int mp[MAX_N][MAX_N],mp_[MAX_N][MAX_N],mp__[MAX_N][MAX_N],r_mx[MAX_N],c_mx[MAX_N],b[MAX_N];

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 1;i<=n;++i)
    {
        for(int j = 1;j<=m;++j)
            scanf("%d",&mp[i][j]);
    }
    for(int i = 1;i<=n;++i)
    {
        for(int j = 1;j<=m;++j)
        {
            b[j] = mp[i][j];
        }
        sort(b+1,b+1+m);
        int sz = unique(b+1,b+1+m)-b-1;
        for(int j = 1;j<=m;++j)
        {
            mp_[i][j] = lower_bound(b+1,b+1+sz,mp[i][j]) - b;
            r_mx[i] = max(r_mx[i],mp_[i][j]);
        }
    }
    for(int i = 1;i<=m;++i)
    {
        for(int j = 1;j<=n;++j)
        {
            b[j] = mp[j][i];
        }
        sort(b+1,b+1+n);
        int sz = unique(b+1,b+1+n)-b-1;
        for(int j = 1;j<=n;++j)
        {
            mp__[j][i] = lower_bound(b+1,b+1+sz,mp[j][i]) - b;
            c_mx[i] = max(c_mx[i],mp__[j][i]);
        }
    }
    for(int i = 1;i<=n;++i)
    {
        for(int j = 1;j<=m;++j)
        {
            int tmp = max(mp_[i][j],mp__[i][j])-min(mp_[i][j],mp__[i][j]);
            if(mp_[i][j]<=mp__[i][j])
            {
                if(r_mx[i]==1) printf("%d",c_mx[j]);
                else printf("%d",max(c_mx[j],r_mx[i]+tmp));
            }
            else
            {
                if(c_mx[j]==1) printf("%d",r_mx[i]);
                else printf("%d",max(r_mx[i],c_mx[j]+tmp));
            }
            j==m?printf("\n"):printf(" ");
        }
    }
    return 0;
}

D

题意 给你一开始一个01串   后来一个01串  问你不改变一开始01串的01个数 使得构造一个01串使后来那个串出现次数最多

做法 我们知道kmp里面的next数组的定义 next[n] 就是这个字符串后next[n]个前缀字符等于后缀

所以我们只需要先构造出一个 然后再构造next[n]后面的答案 不断去构造即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
const int MAX_N = 500025;
char str[MAX_N],mo[MAX_N];
int Next[MAX_N],n2;
void GetNext()
{
    int i=0,j=-1;
    while(i<n2)
    {
        if(j==-1||mo[i]==mo[j])
        {
            ++i,++j,Next[i]=j;
        }
        else
            j=Next[j];
    }
    return ;
}
int main()
{
    int num = 0,num_ = 0,NUM = 0,NUM_ = 0;
    scanf("%s",str);
    int len = strlen(str);
    for(int i = 0;i<len;++i)
    {
        if(str[i]=='1') num++;
        else num_++;
    }
    scanf("%s",mo);
    n2 = strlen(mo);
    for(int i = 0;i<n2;i++)
    {
        if(mo[i]=='1') NUM++;
        else NUM_++;
    }
    Next[0] = -1;
    GetNext();
    //dbg(Next[n2]);
    if(num>=NUM&&num_>=NUM_)
    {
        printf("%s",mo);
        num-=NUM;
        num_ -= NUM_;
        while(num&&num_)
        {
            for(int i = Next[n2];i<n2;i++)
            {
                if(mo[i]=='1') num--;
                else num_--;
                printf("%c",mo[i]);
                if(!num&&NUM||!num_&&NUM_) break;
            }
        }
        while(num)
        {
            printf("1");
            num--;
        }
        while(num_)
        {
            printf("0");
            num_--;
        }
        printf("\n");
    }
    else
    {
        printf("%s\n",str);
    }

    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值