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

A:

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
int n,m;
char a1[200050],a2[200050];
void solve(int x){
    for(int i=1;i<=x-1;i++)if(a1[i]!=a2[i]){
        puts("NO");exit(0);
    }
    int j=m;
    for(int i=n;i>=x+1;i--){
        if(a1[i]!=a2[j--]){
            puts("NO");exit(0);
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    if(n>m+1){puts("NO");return 0;}
    scanf("%s%s",a1+1,a2+1);
    for(int i=1;i<=n;i++)if(a1[i]=='*'){
        solve(i),puts("YES");return 0;
    }
    if(n!=m){
        puts("NO");return 0;
    }solve(n+1);
    puts("YES");
}

B:

給你兩個數n和k,問有多少對(a,b) a<=n,b<=n,a≠b,使得a+b=k

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
long long n,k;
int main(){
    scanf("%lld%lld",&n,&k);
    if(n*2<k)printf("0\n");
    else if(k<=n)printf("%lld\n",(k-1)/2);
    else{
        long long tmp=k-n;
        printf("%lld\n",(n-tmp+1)/2);
    }
}

C:

給你一個括號序列,讓你刪點兒東西,變成長度爲m的合法括號序列

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
int n,m,top;
char s[200050],stk[200050];
int main(){
    scanf("%d%d",&n,&m);
    m=(n-m)/2;
    scanf("%s",s+1);
    for(int i=1;i<=n;i++){
        if(s[i]=='(')stk[++top]=s[i];
        else{
            if(m)--top,--m;
            else stk[++top]=s[i];
        }
    }
    for(int i=1;i<=top;i++)putchar(stk[i]);puts("");
}

D:

對於一個長度n的數組進行q次查詢,i從1到q,第i次將任意一段連續的部分全部染成i。

最後得到的數組中可能會存在“污點”0.即最後對數組的任意子集set爲0.

給出n和q,以及帶污點的長爲n的數組,判斷是否能將其還原成沒有0的合理數組。

如果可以則輸出任意一合理數組。

思路:

首先,一個同樣的數中間不可能夾着比它小的數。

爲了保證q必須出現,需要特判

 

也就是線段樹區間置一,區間求和

(我是怎麼交了10遍才過的,,,)

 

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=200500;
int n,q,a[N],lazy[N<<3],tree[N<<3],lsti,maxx;
vector<int>vec[N];
void push_down(int l,int r,int pos){
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    lazy[pos]=0,lazy[lson]=1,lazy[rson]=1;
    tree[lson]=mid-l+1,tree[rson]=r-mid;
}
int query(int l,int r,int pos,int L,int R){
    if(lazy[pos])push_down(l,r,pos);
    if(l>=L&&r<=R){return tree[pos];}
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    if(mid<L)return query(mid+1,r,rson,L,R);
    else if(mid>=R)return query(l,mid,lson,L,R);
    else return query(l,mid,lson,L,R)+query(mid+1,r,rson,L,R);
}
void insert(int l,int r,int pos,int L,int R){
    if(lazy[pos])push_down(l,r,pos);
    if(l>=L&&r<=R){lazy[pos]=1;tree[pos]=r-l+1;return;}
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    if(mid<L)insert(mid+1,r,rson,L,R);
    else if(mid>=R)insert(l,mid,lson,L,R);
    else insert(l,mid,lson,L,R),insert(mid+1,r,rson,L,R);
    tree[pos]=tree[lson]+tree[rson];
}
int main(){
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        vec[a[i]].push_back(i);
        if(!a[i])lsti=i,insert(1,n,1,i,i);
        maxx=max(maxx,a[i]);
    }
    if(maxx!=q&&(!lsti)){puts("NO");return 0;}
    for(int i=0;i<=q;i++)sort(vec[i].begin(),vec[i].end());
    for(int i=q;i;i--){
        int tmp=vec[i].size();
        if(!tmp)continue;
        int bgn=vec[i][0],end=vec[i][vec[i].size()-1];
        if(end-bgn+1<tmp+query(1,n,1,bgn,end)){puts("NO");return 0;}
        insert(1,n,1,bgn,end);
    }
    for(int i=1;i<=n;i++){
        if(a[i])break;
        a[i]=1;
    }
    for(int i=1;i<=n;i++)if(!a[i])a[i]=a[i-1];
    if(maxx!=q&&lsti)a[lsti]=q;
    puts("YES");
    for(int i=1;i<=n;i++)printf("%d ",a[i]);
}

E:

構造題

給一個n*n的矩陣,中間有障礙,你可以詢問(x1,y1),(x2,y2)表示從(x1,y1)能不能到(x2,y2)

其中,兩個點的曼哈頓距離>=n

從(1,1)不斷向右下挪

當曼哈頓距離==n的時候

把(n,n)向左上挪

#include <string>
#include <iostream>

using namespace std;

int n;

bool vis[1005][1005];

bool query(int x, int y)
{
    if (x + y <= n + 1)
        cout << "? " << x << " " << y << " " << n << " " << n << endl;
    else
        cout << "? " << 1 << " " << 1 << " " << x << " " << y << endl;
    cout.flush();
    string s;
    cin >> s;
    return s[0] == 'Y';
}

void search1(int x, int y)
{
    vis[x][y] = true;
    if (x + y == n + 1)
        return;
    if (query(x, y + 1))
        search1(x, y + 1);
    else
        search1(x + 1, y);
}

void search2(int x, int y)
{
    vis[x][y] = true;
    if (x + y == n + 1)
        return;
    if (query(x - 1, y))
        search2(x - 1, y);
    else
        search2(x, y - 1);
}

void putanswer()
{
    cout << "! ";
    int x = 1, y = 1;
    while (x != n || y != n)
    {
        if (vis[x][y + 1])
        {
            cout << "R";
            y = y + 1;
        }
        else if (vis[x + 1][y])
        {
            cout << "D";
            x = x + 1;
        }
    }
    cout << endl;
    cout.flush();
}

int main()
{
    cin >> n;
    search1(1, 1);
    search2(n, n);
    putanswer();
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章