题解:P11247 [GESP202409 六级] 算法学习
Eddie08012025 · · 题解
2025/4/24:改正了评论里提出的一些代码错误。
2025/5/30:再次改正了评论中提出的一些代码和思路错误。
2025/8/19:再次改正了评论中提出的一些代码和思路错误。
(数据过水)(数据过水)
思路
显然,对于每个知识点做能得到更多经验值的题目更优。
这样,我们可以用一个 pair 来存储这道题的经验值,这道题的知识点,进行排序,这样系统默认第一个元素为第一关键字,第二个元素为第二关键字,从小到大排序。
然后,就要开始选择题目。从
当有任何一个知识点还没有达到 -1。
由于题目说:连续做同样知识点的题是不好的,这样选择题数最高的知识点是应该重点考虑的,当
如果要保证不会连续做两道同样知识点的题,需要保证
注意:要存储选择了最多题的知识点总题数,以免没有足够的题去乱做,使无法让两道同样知识点的题不一起做。
例如:
2 6 10
1 1 1 1 1 2
5 3 2 1 1 10
这样一定要选的是
代码:
#include<bits/stdc++.h>
using namespace std;
int m,n,k,b[100001],c[100001],anss,ans,maxn,maxk=1e9,ti[100001];
pair<int,int>a[100001];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>m>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i].second;
ti[a[i].second]++;
}for(int i=1;i<=n;i++){
cin>>a[i].first;
}sort(a+1,a+n+1);
for(int i=n;i>=1;i--){
if(b[a[i].second]<k){
b[a[i].second]+=a[i].first;//统计现在的经验值
if(b[a[i].second]>=k)anss++;//统计有多少个知识点达到了k
ans++;//增加题数
c[a[i].second]++;//统计每个知识点的选择题数
if(maxn<c[a[i].second])maxn=c[a[i].second],maxk=ti[a[i].second];//统计选择最多题的知识点选择了的题数
else if(maxn==c[a[i].second])maxk=min(ti[a[i].second],maxk);
//另外 maxk 存储选择了最多题的知识点总题数,以免没有足够的题去乱做,使无法让两道同样知识点的题不一起做。
}
}if(anss!=m||maxn*2-1>n||maxn>n-maxk)cout<<"-1";//输出
else cout<<max(maxn*2-1,ans);
return 0;
}
注:一组 hack 数据(评论区中提出的,可以 hack 掉一部分题解):
2 9 7
2 2 1 1 1 2 1 1 1
1 3 1 9 2 3 9 7 8
output: 5