[CF]Codeforces Round #551 (Div. 2)

时间:2022-09-10 15:59:17

solved 4

 

A

题意:签到

[CF]Codeforces Round #551 (Div. 2)[CF]Codeforces Round #551 (Div. 2)
#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define ll long long 
#define pii pair<int,int<
#define mp make_pair
#define pb push_back
#define st first
#define nd second

int main(){
    int n,t;
    cin>>n>>t;
    int ans=1e6,ans2=0;
    rep(i,n){
        int s,d;
        cin>>s>>d;
        while(s<t){
            s+=d;
        }
        if(s-t<ans){
            ans=s-t;
            ans2=i;
        }
    }
    cout<<ans2<<endl;
}
View Code

00:09(1A)

 

B

题意:给出三视图,求任意一个符合的几何体

考虑俯视图,一个点如果是0则这里一定没有块,如果是1就让高度为主视图中该列高度和左视图中该行高度的较小值,证明显然。

[CF]Codeforces Round #551 (Div. 2)[CF]Codeforces Round #551 (Div. 2)
#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define ll long long 
#define pii pair<int,int<
#define mp make_pair
#define pb push_back
#define st first
#define nd second

const int N=1e2+7;

int a[N],b[N],ans[N][N];

int main(){
    int n,m,h;
    cin>>n>>m>>h;
    rep(i,m)cin>>a[i];
    rep(i,n)cin>>b[i];
    rep(i,n){
        rep(j,m){
            cin>>ans[i][j];
            if(ans[i][j]!=0)ans[i][j]=min(a[j],b[i]);
            cout<<ans[i][j]<<" ";
        }
        cout<<endl;
    }    
}
View Code

00:18(1A)

 

C

题意:一个含?的括号序列,?可以赋值为(或),求一种赋值方法使这个序列合法,且这个序列的每个真前缀都不合法。

要让真前缀都不合法,应该把左括号尽量放到前边,整个序列一定有l/2个左括号,记录下原本的左括号数量,然后从左到右扫一遍,还有剩余左括号就赋值为左括号,否则赋值为右括号。

(开始想麻烦了。。自闭了好久)

[CF]Codeforces Round #551 (Div. 2)[CF]Codeforces Round #551 (Div. 2)
#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define ll long long 
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define st first
#define nd second

string ans;

const int N=3e5+7;

int main(){
    int l;
    cin>>l;
    string s;
    cin>>s;
    int now=0;
    int sum=0;

    for(int i=0;i<l;i++)
        if(s[i]=='(')sum++;

    if(l&1){
        cout<<":(";
        return 0;
    }
    for(int i=0;i<l;i++){
        if(s[i]=='('){
            ans+='(';
            now++;
        }
        if(s[i]==')'){
            ans+=')';
            now--;
            if(i!=s.size()-1&&now<=0){
                cout<<":(";
                return 0;
            }
        }
        if(s[i]=='?'){
            if(sum<l/2){
                ans+='(';
                sum++;
                now++;
            }
            else {
                ans+=')';
                now--;
                if(i!=l-1&&now<=0){
                    cout<<":(";
                    return 0;
                }
            }
    }
    }
    if(now!=0)cout<<":(";
    else cout<<ans;
}
View Code

01:20(5A)

 

D

题意:给出一棵有根树,有k个叶子节点,每个叶子节点可以赋值为1-k中的一个整数值,且不能重复。其他节点有一个属性,可以是Max或Min,意为这个节点的值是他所有儿子值的最大值或最小值。求根节点的最大值。

简单树形DP,sz[x]为k减去这个节点能达到的最大值再加一,每个叶子节点的sz为1,对于min节点,他的sz为所有儿子的sz和,对于max节点,他的sz为所有儿子sz的最小值。

[CF]Codeforces Round #551 (Div. 2)[CF]Codeforces Round #551 (Div. 2)
#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define ll long long 
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define st first
#define nd second

string ans;

const int N=3e5+7;

int f[N],a[N],sz[N];

vector<int> e[N];

int n,k;

void dfs(int x){
    if(e[x].size()==0){
        sz[x]=1;
        k++;
        return ;
    }
    for(int i=0;i<e[x].size();i++){
        if(f[x]==e[x][i])continue;
        dfs(e[x][i]);
        if(a[x]==0){
            sz[x]+=sz[e[x][i]];
        }
        else {
            if(sz[x]==0||sz[e[x][i]]<sz[x])sz[x]=sz[e[x][i]];
        }
    }
}

int main(){
    cin>>n;
    rep(i,n)cin>>a[i];
    rep(i,n-1){
        int x;
        cin>>x;
        f[i+1]=x;
        e[x].pb(i+1);
    }
    dfs(1);
    cout<<k-sz[1]+1;
}
View Code

01:37(1A)