Codeforces Round #658 (Div. 2) A,B,C,D

  1. A - Common Subsequence

A题就特别简单大水题,找a,b两个数组中是否有相同元素,如果有,输出一个,没了。

int a[1005],b[1005];
void sove()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&b[i]);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(a[i]==b[j])
            {
                printf("YES\n1 %d\n",a[i]);
                return;
            }
        }
    }
    printf("NO\n");
}
  1. B - Sequential Nim

B题我吐了想到了写了好久,只要比较前面1的个数然后后面的就不用管了,具体看代码,看不懂仔细想想,先手的人肯定占绝对优势,而前面的1就是让先手的人失去优势的东西。

int a[maxn],b[1005];
void sove()
{
    int n;
    scanf("%d",&n);
    int cnt1=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    if(n==1)
    {
        printf("First\n");
        return;
    }
    int cnt=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==1)
        {
            cnt++;
        }
        else
        {
            break;
        }
    }
    if(cnt==n)//我没特判一直不对,调了半天
    {
        if(cnt%2==1)
        {
            printf("First\n");
        }
        else
        {
            printf("Second\n");
        }
        return ;
    }
    if(cnt%2==1)
    {
        printf("Second\n");
    }
    else
    {
        printf("First\n");
    }
}
  1. B - Prefix Flip (Hard Version)

这一题我也只能说只可意会不可言传了,拿起你的笔对着代码写一遍你就懂了,可能不需要写一遍写个三四个数字就知道了

char a[maxn],b[maxn];
vector<int>ans;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ans.clear();
        int n;
        scanf("%d",&n);
        scanf("%s%s",a+1,b+1);
        for(int i=2;i<=n;i++)
        {
            if(a[i]!=a[i-1])
            {
                ans.push_back(i-1);
            }
        }
        char last=a[n];
        for(int i=n;i>=1;i--)
        {
            if(last!=b[i])
            {
                ans.push_back(i);
                last=last=='0'?'1':'0';
            }
        }
        printf("%d\n",ans.size());
        for(int i=0;i<ans.size();i++)
        {
            printf("%d ",ans[i]);
        }
        printf("\n");
    }
    return 0;
}
  1. D - Unmerge

这一题我是根本没有想到的,还能这么搞,居然直接转移成01背包了,真厉害,在下实在是佩服,你可以对着样例看看,是不是每出现一个比较大的值,后面一直要到出现比这个值大的数的时候才会停止加入数列a或者数列b中,这样我们把每个单个的这种序列都抽出来他们的大小,然后看是否可以组成n这么大的两个新数列,这个就用01背包完成

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define se second
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 5e5 + 50;
const int maxm = 1.5e5+50;
const double eps = 1e-7;
const double inf = 0x3f3f3f3f;
const ll  lnf  = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const  double pi=3.141592653589;
int n,a[4005],dp[4005];
vector<int>ans;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        n=2*n;
        ans.clear();
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1,j=1;i<=n;i++)
        {
            j=i;
            while(j<=n&&a[i]>=a[j])
            {
                j++;
            }
            ans.push_back(j-i);
            i=j-1;
        }
        ms(dp,0);
        dp[0]=1;
        for(int i=0;i<ans.size();i++)
        {
            for(int j=n;j>=0;j--)
            {
                if(j-ans[i]>=0&&dp[j-ans[i]])
                {
                    dp[j]=1;
                }
            }
        }
        if(dp[n/2])
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qcccc_/article/details/107559978