Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A-D

A. Single Wildcard Pattern Matching

题目链接

题意:给定两个串,其中第一个串最多有一个*,可以匹配任意长字符,判断两个字符串能否匹配

思路:确定*的位置,判断前缀和后缀是否相等即可。

PS:这题好坑啊

AC代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<>N>>M)
    {
        cin>>s>>t;
        pos = s.length();
        for(int i=0;ipos;--i,++cur)
            {
                if(t.length()-cur

 

 

B. Pair of Toys

题目链接

题意:问1到N的数字中选两个组成K的方式有多少个。

思路:随手比划几个。

AC代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<>N>>K)
    {
        if(K>=2LL*N)
        {
            cout<<0<

 

C. Bracket Subsequence

题目链接

题意:给一个由( 和 ) 组成的串,求一个满足给定条件的长为k的子序列,答案保证存在。

思路:水题,暴力求K/2个左括号,最后补全就好了。

AC代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)< togo;
char ans[MAXN];

int main()
{
    //freopen("input","r",stdin);
    //freopen("output","w+",stdout);
    while(scanf("%d%d",&N,&K)!=EOF)
    {
        scanf("%s",s);
        while(!togo.empty())    togo.pop();
        int curno = 0;
        int fitno = 0;
        int cur = 0;
        int len = strlen(s);
        for(int i=0;i

 

D. Array Restoration
题目链接

题意:对一个长为N的串做Q次处理,第i次处理为令 L_i, R_i的数字为i,最后令一个子集中数字为0(可以是空)。给定最后结果串,试求最后一个操作之前的串。

思路:总的来说有两步,填零和合法性判断。

首先一个合法串最后至少有一个数字为Q,且不存在形如ABA且B

当原串存在零时,如果没有Q则填入Q,否则填入与该0区域相接的数字。

判断时,对该串建立一个最小值的线段树。从左到右遍历,记录某数字最早出现的位置,当它再次出现时,查询该区域最小值,如果小于该数字,则原串非法,否则继续遍历。

AC代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<>1;
    if(pos<=m)  update(pos,num,l,m,rt<<1);
    else    update(pos,num,m+1,r,rt<<1|1);
    dat[rt] = min(dat[rt<<1],dat[rt<<1|1]);
}

int query( int ql, int qr,int l, int r, int rt)
{
    if(l>=ql && r<=qr)  return dat[rt];
    int m = (l+r)>>1;
    int maxn = MAXN;
    if(ql<=m)    maxn=min(maxn,query(ql,qr,l,m,rt<<1));
    if(qr>m)    maxn=min(maxn,query(ql,qr,m+1,r,rt<<1|1));
    return maxn;
}

int cur;

void build(int l, int r, int rt)
{
    if(l==r)
    {
        scanf("%d",dat+rt);
        arr[cur++] = dat[rt];
        return;
    }
    int m = (l+r)>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    dat[rt] = min(dat[rt<<1],dat[rt<<1|1]);
}

int N, Q;
int mkpos[MAXN];

int main()
{
    //freopen("input","r",stdin);
    //freopen("output","w+",stdout);
    while(scanf("%d%d",&N,&Q)!=EOF)
    {
        cur = 1;
        build(1,N,1);
        int flag_q = 0;
        for(int i=1;i<=N;++i)
        {
            if(arr[i]==Q)
            {
                flag_q = 1;
                break;
            }
        }
        int leftno;
        int rightno;
        for(int i=1;i<=N;++i)
        {
            if(arr[i]==0)
            {
                if(i>1) leftno = arr[i-1];
                else    leftno = -1;
                rightno = -1;
                int j;
                for(j=i+1;j<=N;++j)
                    if(arr[j])
                    {
                        rightno = arr[j];
                        break;
                    }
                if(leftno==rightno&&leftno==-1)
                {
                    for(int t=i;t

 

 

你可能感兴趣的:(ACM,Codeforces)