Codeforces Round 975 (Div. 2) A~C

A. Max Plus Size

当字符串长度为偶数是,size=n/2,

长度为奇数时,分类讨论最大值在奇数位还是偶数位,判断时加入i%2和d%2

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(a) a.begin(),a.end()
void solve(){
    ll n,m=0,d=0;
    cin>>n;
    vector<ll> p(n+1);
    for(ll i=1;i<=n;i++){
        cin>>p[i];
        if(m<=p[i]){
            if(n%2){
                if((p[i]+i%2)>(m+d%2)){
                    m=p[i];
                    d=i;
                }
            }
            else {
                m=p[i];
                d=i;
            }
        }
    }
    if(n%2&&d%2)cout<<m+n/2+1<<'\n';
    else cout<<m+n/2<<'\n';
} 
int main(){
    #ifdef Online_Judge
    freopen("INPUT.in","r",stdin);
    freopen("OUTPUT.out","w",stdout);
    #endif
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin>>t;
    while(t--)
        solve();
    return 0;
}

B. All Pairs Segments

可以直接计算覆盖线段数(见代码),O(n)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(a) a.begin(),a.end()
void solve(){
    ll n,Q,tim=0;
    cin>>n>>Q;
    vector<ll> p(n+1),q(Q);
    map<ll,ll> cnt;
    for(ll i=1;i<=n;i++)cin>>p[i];
    for(ll i=0;i<Q;i++)cin>>q[i];
    sort(p.begin(),p.end());
    if(n==2){
        cnt[1]=p[n]-p[n-1]+1;
    }
    else{
        for(ll i=2;i<n;i++){
            tim=(i-1)*(n-i+1)+n-i;
            cnt[tim]++;
            tim=i*(n-i);
            cnt[tim]+=p[i+1]-p[i]-1;
        }
        cnt[n-1]+=p[2]-p[1]+1;
    }
    for(auto i:q){
        cout<<cnt[i]<<' ';
    }
    cout<<'\n';
} 
int main(){
    #ifdef Online_Judge
    freopen("INPUT.in","r",stdin);
    freopen("OUTPUT.out","w",stdout);
    #endif
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin>>t;
    while(t--)
        solve();
    return 0;
}

C. Cards Partition

鸽巢原理。子集大小为s(1<=s<=n),数量最多的牌a有x张,牌的总数为sum(也就是pre[n]),满足(sum+k)/s>=x(因为至少有x个子集可以分配x个a),并且需要整除,即[sum,sum+k]上存在一个数是s的倍数。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(a) a.begin(),a.end()
void solve(){
    ll n,k;
    cin>>n>>k;
    vector<ll> p(n+1),pre(n+1);
    for(ll i=1;i<=n;i++){
        cin>>p[i];
    }sort(p.begin(),p.end());
    for(ll i=1;i<=n;i++){
        pre[i]=pre[i-1]+p[i];
    }
    ll s=n;
    for(;s>=1;s--){
        if(p[n]*s<=pre[n]+k){
            if((pre[n]+k)%s<=k)
            {
                cout<<s<<'\n';
                return ;
            }
        }
    }
    cout<<1<<'\n';
} 
int main(){
    #ifdef Online_Judge
    freopen("INPUT.in","r",stdin);
    freopen("OUTPUT.out","w",stdout);
    #endif
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin>>t;
    while(t--)
        solve();
    return 0;
}

D. Speedbreaker

时间为t的城市,出现在[l,r],如果r-l+1>t,就说明无法全部占领,若可以,开始的点可能在[r-t+1,l+t-1],t从最小的开始遍历,同时更新l和r。统计被所有情况覆盖的城市数量,用差分。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(a) a.begin(),a.end()
void solve(){
    ll n,ans=0,x;
    cin>>n;
    vector<ll> a(n+1),b(n+1,n+1),diff(n+2);
    vector<ll> p(n+1),cnt(n+1);
    for(ll i=1;i<=n;i++){
        cin>>x;
        p[i]=x;
        cnt[x]++;
        a[x]=max(a[x],i);
        b[x]=min(b[x],i);
    }
    if(p[1]<n&&p[n]<n){
        cout<<"0\n";
        return ;
    }
    ll s=1;
    ll l=n,r=1;
    sort(p.begin(),p.end());
    for(ll i=1;i<=n;i+=cnt[p[i]]){
        l=min(l,b[p[i]]);
        r=max(r,a[p[i]]);
        if(p[i]<r-l+1){
            cout<<"0\n";
            return ;
        }
        else{
            ll nl=max(r-p[i]+1,s);
            ll nr=min(l+p[i]-1,n);
            diff[nl]+=cnt[p[i]];diff[nr+1]-=cnt[p[i]];
        }
    }
    for(ll i=1;i<=n;i++){
        diff[i]+=diff[i-1];
        ans+=(diff[i]==n);
    }cout<<ans<<'\n';
} 
int main(){
    #ifdef Online_Judge
    freopen("INPUT.in","r",stdin);
    freopen("OUTPUT.out","w",stdout);
    #endif
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin>>t;
    while(t--)
        solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值