Codeforces Round #600 (Div. 2)

A. Single Push

题目大意:给定两个数组,问你能不能给A数组连续一段加一个数字,使得其等于B数组。

分析:模拟一下即可,就不用想太多了。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
typedef long long ll;
ll a[maxn],b[maxn];
int main(){
    int t,n;
    cin>>t;
    while(t--){
        cin>>n;
        for(int i=0;i<n;i++)
            cin>>a[i];
        for(int i=0;i<n;i++)
            cin>>b[i];
        ll tol=0;
        int l,r;
        for(int i=0;i<n;i++)
            tol+=b[i]-a[i];
        if(!tol)
            cout<<"YES"<<endl;
        else{
            for(int i=0;i<n;i++){
                if(a[i]!=b[i]){
                    l=i;
                    break;
                }
            }
            for(int i=n-1;i>=0;i--){
                if(a[i]!=b[i]){
                    r=i;
                    break;
                }
            }
            ll re=b[l]-a[l];
            bool f=true;
            for(int i=l;i<=r;i++){
                if(re+a[i]!=b[i]){
                    f=false;
                    break;
                }
            }
            if(f){
                if(re<=0)
                    cout<<"NO"<<endl;
                else
                    cout<<"YES"<<endl;
            }
            else{
                cout<<"NO"<<endl;
            }
        }
    }
    return 0;
}

B. Silly Mistake

题目大意:给定一个数组,然后正整数表示这个人到达,负数代表其相反数这个人离开,问你每天有多个人到达(到达且离开才表示一次成功)。

分析:也是模拟,但是比第一个稍微复杂一点。需要逻辑思维比较清楚。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
int cnt[maxn];
map<int,int> vis;
set<int> s;
int main() {
    int n, x;
    cin >> n;
    bool f = true;
    int day = 1;
    for (int i = 0; i < n; i++) {
        cin >> x;
        if (x < 0) {
            if (s.count(-x)) {
                s.erase(s.find(-x));
            } else {
                f = false;
            }
        } else {
            if(vis[x]==day) {
                if (s.size() || s.find(x) != s.end())
                    f = false;
            }
            vis[x] = day;
            cnt[day]++;
            s.insert(x);
        }
        if (!s.size() && i != n - 1)
            day++;
    }


    if (s.size())
        f = false;
    if (!f)
        cout << -1 << endl;
    else {
        cout << day << endl;
        for (int i = 1; i <= day; i++) {
            cout << 2*cnt[i] << (i == day ? '\n' : ' ');
        }
    }
    return 0;
}

C. Sweets Eating

题目大意:每天只能吃m个甜点,第i天吃第s个甜品的花费是i*a[s]。问你怎么样能使得吃每个甜品的花费最小。

分析:线性dp,如果i小于m,dp[i+1]=sum,否则,dp[i+1]=dp[i-m+1]+sum。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
typedef long long ll;
ll a[maxn];
ll dp[maxn];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n,less<ll>());
    ll sum=0;
    for(int i=0;i<n;i++){
        sum+=a[i];
        if(i<m)
            dp[i+1]=sum;
        else
            dp[i+1]=dp[i-m+1]+sum;
    }
    for(int i=1;i<=n;i++)
        cout<<dp[i]<<(i==n?'\n':' ');
    return 0;
}
posted @ 2020-01-05 18:54  SwiftAC  阅读(108)  评论(0编辑  收藏  举报