1. 程式人生 > >Codeforces Round #530 (Div. 2) A,B,C,D

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");
}