CodesForces 831C Round #424 Div2C:Set乱搞

题意:给出k个评委打出的分数delta[i],再给出n(<=k)个分数score[i],这些分数是评审过程中的中间分,也就是每个score[i]都是initScore+sum[j]得到的。现在求initScore可能的取值有几种,如果score不合法输出0。

题解:考虑某一种使得score合法的方案。比如说是这样的情况:score[1],score[2],……score[n]分别是第G1,G2,……,Gn号评委打完分之后的中间分。那么这种方案的initScore有这样的性质:initScore=score[1]-sum[G1]=score[2]-sum[G2]=……=score[n]-sum[Gn]。而这样的方案组合无非有nk种,而且我们知道一个可能的initScore一定会被认可n次。

于是我们的算法可以这样描述:枚举每个ni,再枚举每个ki,尝试将score[ni]看作是评委ki打完分得到的中间分,去算一个initScore的可能值,这样得到了k个可能值,这些值是仅考虑score[ni]的位置而得到的initScore可能值,我们只需要在这样得到的n个集合中,取交集即可。(而且题目保证score[i]都不相同,因此每个位置只可能被放置一个score)。

Code:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 2005
set<int> S1,S2;
int score[MAXN],delta[MAXN],sum[MAXN];
int k,n;
int main(){
    cin>>k>>n;
    for (int i=1;i<=k;i++){
        cin>>delta[i];
        sum[i]=sum[i-1]+delta[i];
    }
    for (int i=1;i<=n;i++){
        cin>>score[i];
    }
    for (int i=1;i<=n;i++){
        S2.clear();
        for (int j=1;j<=k;j++){
            if (i==1||S1.find(score[i]-sum[j])!=S1.end()){
                S2.insert(score[i]-sum[j]);
//                cout<<score[i]-sum[j]<<endl;
            }
        }
        S1=S2;
    }
    cout<<S1.size();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值