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

A. Snowball

链接:http://codeforces.com/contest/1099/problem/A

思路:模拟

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m = (l + r) >> 1

const int M = 1e5 + 10;
int n,m,x[4],y[4];
int main()
{
    cin>>n>>m;
    for(int i = 1;i <= 2;i ++){
        cin>>x[i]>>y[i];
    }
    for(int i = m;i >= 0;i --){
        n += i;
        for(int j = 1;j <= 2;j ++){
            if(i == y[j])
                n-=x[j];
        }
        n = max(n,0);
    }
    cout<<n<<endl;
}

B. Squares and Segments

链接:http://codeforces.com/contest/1099/problem/B

思路:思维题

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m = (l + r) >> 1

const int M = 1e5 + 10;
int n,k,cnt;
int main()
{
    cin>>n;
    for(int i = 1;i <= n;i ++){
        k = 4*i*i;
        if(n <= k){
            cnt = 2*i;break;
        }
    }
    int ans =  k - n;
    if(ans < cnt) cout<<cnt*2<<endl;
    else if(ans < 2*cnt-1) cout<<cnt*2-1<<endl;
    else if(ans < 3*cnt-2) cout<<cnt*2-2<<endl;
    else cout<<cnt*2-3<<endl;
}

C. Postcard

链接:http://codeforces.com/contest/1099/problem/C

思路:题意可得,*号可以无限复制可以删除也可以不动,那么会让长度变长的只有*,*和?都可以使长度变短。那么根据当前序列长度和想要的长度,改一下就好了,答案不唯一

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m = (l + r) >> 1

const int M = 1e5 + 10;
int n,ans,ans2,ans1;
int main()
{
    string s;
    cin>>s;
    cin>>n;
    int len = s.size();
    for(int i = 0;i < len;i ++){
        if(s[i]=='*')
            ans1++;
        else if(s[i]=='?')
            ans2++;
        else
            ans++;
    }
    if(ans-ans1-ans2 > n) cout<<"Impossible"<<endl;
    else if(ans1==0&&ans < n) cout<<"Impossible"<<endl;
    else{
        if(ans >= n){
            int cnt = ans - n;
            for(int i = 0;i < len;i ++){
                if((s[i+1]=='?'||s[i+1]=='*')&&cnt) cnt--;
                else if(s[i]=='?'||s[i]=='*') continue;
                else cout<<s[i];
            }
            cout<<endl;
        }
        else{
            int cnt = n - ans;
            for(int i = 0;i < len;i ++){
                if(s[i]=='*'&&cnt){
                    for(int j = 1;j <= cnt;j ++){
                        cout<<s[i-1];
                    }
                    cnt = 0;
                }
                else if(s[i]!='*'&&s[i]!='?')cout<<s[i];
            }
            cout<<endl;
        }
    }
    return 0;
}

D. Sum in the tree

链接:http://codeforces.com/contest/1099/problem/D

思路:比较简单的dfs吧。。结果dfs的调用写捞了应该取完值再去调用,写成先调用再取值了。

因为题目给的赋值其实是当前节点到根节点的前缀和,那么对于偶数层为了使总体最优肯定是将他的值假设为子节点中最小的值,奇数层已经有赋值就可以不用处理,对于每个节点来说本身的值就是当前点的前缀和减去父节点的前缀和,最后统计一遍所有的点的本身值就好了

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid ll m = (l + r) >> 1

const ll M = 1e5 + 10;
const ll inf = 1e18+7;
ll head[M],cnt,flag;
ll ans,a[M],b[M];
vector<ll>g[M];
void dfs(ll u,ll fa,ll dep){
    ll mn = inf;
    if(dep%2==0){
        for(ll i = 0;i < g[u].size();i ++){
            ll v = g[u][i];
            mn = min(mn,a[v]);
        }
        if(mn != inf) a[u] = mn,b[u] = a[u] - a[fa];
        else a[u] = a[fa],b[u] = 0;
    }
    else{
        b[u] = a[u] - a[fa];
    }
    for(ll i = 0;i < g[u].size();i ++){
            ll v = g[u][i];
            dfs(v,u,dep+1);
        }
}

int main()
{
    ll n,x;
    scanf("%lld",&n);
    for(ll i = 2;i <= n;i ++){
        scanf("%lld",&x);
        g[x].push_back(i);
    }
    for(ll i = 1;i <= n;i ++){
        scanf("%lld",&a[i]);
    }
    dfs(1,0,1);
    for(ll i = 1;i <= n;i ++){
        ans += b[i];
        if(b[i] < 0) flag = 1;
    }
    if(!flag) printf("%lld\n",ans);
    else printf("-1\n");
}

猜你喜欢

转载自www.cnblogs.com/kls123/p/10263527.html