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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Lfhase/article/details/81798342

A. Single Wildcard Pattern Matching

题目链接

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

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

PS:这题好坑啊

AC代码:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <stack>
#include <bitset>

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<<endl;
#define ll long long
#define EPS 1e-6
#define pb push_back

const int MAXN = 500005;
const int MOD = 1e9+7;
const int INF = 1e9+7;

int _;

using namespace std;

string s, t;
int pos;
int N, M;

int main()
{
    //freopen("input","r",stdin);
    //freopen("output","w+",stdout);
    FSIO;
    while(cin>>N>>M)
    {
        cin>>s>>t;
        pos = s.length();
        for(int i=0;i<s.length();++i)
            if(s[i]=='*')
            {
                pos = i;
                break;
            }
        int flag = 1;
        if(pos==s.length()&&s.length()!=t.length()) flag = 0;
        else
            for(int i=0;i<pos;++i)
            {
                if(s[i]!=t[i])
                {
                    flag = 0;
                    break;
                }
            }
        if(flag)
        {
            int cur = 1;
            for(int i=s.length()-1;i>pos;--i,++cur)
            {
                if(t.length()-cur<pos||s[i]!=t[t.length()-cur])
                {
                    flag = 0;
                    break;
                }
            }
        }
        if(flag)    cout<<"YES"<<endl;
        else    cout<<"NO"<<endl;
    }


    return 0;
}

B. Pair of Toys

题目链接

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

思路:随手比划几个。

AC代码:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <stack>
#include <bitset>

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<<endl;
#define ll long long
#define EPS 1e-6
#define pb push_back

const int MAXN = 500005;
const int MOD = 1e9+7;
const int INF = 1e9+7;

int _;

using namespace std;



int main()
{
    //freopen("input","r",stdin);
    //freopen("output","w+",stdout);
    FSIO;
    ll N;
    ll K;
    while(cin>>N>>K)
    {
        if(K>=2LL*N)
        {
            cout<<0<<endl;
            continue;
        }
        ll rightno = min(N,K);
        if(rightno==K)  rightno -= 1LL;
        ll leftno = K - rightno;
        ll res = (rightno-leftno+1LL)/2LL;
        cout<<res<<endl;
    }

    return 0;
}

C. Bracket Subsequence

题目链接

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

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

AC代码如下:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <stack>
#include <bitset>

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<<endl;
#define ll long long
#define EPS 1e-6
#define pb push_back

const int MAXN = 200005;
const int MOD = 1e9+7;
const int INF = 1e9+7;

int _;

using namespace std;

int N, K;
char s[MAXN];
queue<char> 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<len;++i)
        {
            if(s[i]=='(')
            {
                ans[cur] = s[i];
                cur++;
                curno++;
                if(curno==K/2)
                {
                    for(int i=fitno;i<=curno;++i)
                        ans[cur++]=')';
                    break;
                }
            }
            else if(s[i]==')')
            {
                ans[cur] = s[i];
                fitno++;
                cur++;
            }
        }
        ans[K] = 0;
        printf("%s\n",ans);
    }
    return 0;
}

D. Array Restoration
题目链接

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

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

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

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

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

AC代码如下:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <stack>
#include <bitset>

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<<endl;
#define ll long long
#define EPS 1e-6
#define pb push_back

const int MAXN = 200005;
const int MOD = 1e9+7;
const int INF = 1e9+7;

int _;

using namespace std;

int dat[MAXN<<2|1];
int arr[MAXN];

void update(int pos, int num, int l, int r, int rt)
{
    if(l==r)
    {
        dat[rt] = num;
        return;
    }
    int m = (l+r)>>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<j;++t)
                    {
                        arr[t] = Q;
                        update(t,Q,1,N,1);
                    }
                }
                else
                {
                    if(!flag_q)
                    {
                        for(int t=i;t<j;++t)
                        {
                            arr[t] = Q;
                            update(t,Q,1,N,1);
                        }
                        flag_q = 1;
                    }
                    else
                    {
                        int num = max(leftno,rightno);
                        for(int t=i;t<j;++t)
                        {
                            arr[t] = num;
                            update(t,num,1,N,1);
                        }
                    }
                }
            }
        }
        int flag = 1;
        memset(mkpos,-1,sizeof(mkpos));
        for(int i=1;i<=N;++i)
        {
            if(mkpos[arr[i]]==-1)    mkpos[arr[i]] = i;
            else
            {
                int test =  mkpos[arr[i]];
                int num = query(mkpos[arr[i]],i,1,N,1);
                if(num<arr[i])
                {
                    flag = 0;
                    break;
                }
            }
        }
        if(flag)
        {
            flag_q = 0;
            for(int i=1;i<=N;++i)
                if(arr[i]==Q)
                {
                    flag_q = 1;
                    break;
                }
            if(!flag_q) flag = 0;
        }
        if(flag)
        {
            printf("YES\n");
            for(int i=1;i<N;++i)
                printf("%d ",arr[i]);
            printf("%d\n",arr[N]);
        }
        else    printf("NO\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Lfhase/article/details/81798342
今日推荐