1 条题解
-
0
这一题暴力模拟+排序的话,很显然会超时。
考虑优化排序,我们可以在输入完数据后先进行一次排序,然后模拟比赛过程,模拟时除了更新分数,顺便处理出两个队列,分别存储胜者和败者,两个队列中的元素仍然能够保持有序,然后再将两个队列归并回原数组中。这一过程是级别的,不会超时。
AC代码:
#include<bits/stdc++.h> #define ll long long using namespace std; const ll N=1e5+5; ll n,r,q; struct node{ ll s,w,id; // s是score即分数,w是实力值,id顾名思义 }a[2*N]; bool cmp(node x,node y){ return x.s==y.s?x.id<y.id:x.s>y.s; // 按照题目中给出的要求排序 } void merge(){ for(ll i=1;i<=r;i++){ queue<node> p1,p2; for(ll i=1;i<=2*n;i+=2) // 模拟比赛过程,并处理出胜者和败者 if(a[i].w>a[i+1].w) a[i].s++,p1.push(a[i]),p2.push(a[i+1]); else a[i+1].s++,p1.push(a[i+1]),p2.push(a[i]); for(ll i=1;i<=2*n;i++) // 归并过程 if(p1.empty()) a[i]=p2.front(),p2.pop(); else if(p2.empty()) a[i]=p1.front(),p1.pop(); else if(cmp(p1.front(),p2.front())) a[i]=p1.front(),p1.pop(); else a[i]=p2.front(),p2.pop(); } } int main(){ scanf("%lld%lld%lld",&n,&r,&q); for(ll i=1;i<=2*n;i++) scanf("%lld",&a[i].s),a[i].id=i; for(ll i=1;i<=2*n;i++) scanf("%lld",&a[i].w); sort(a+1,a+1+2*n,cmp); // 先排序 merge(); printf("%lld",a[q].id); // 最后输出第q名的id return 0; }
归并过程中将队列中的直接赋值到数组中时是不会报错的,并不需要重载=运算符(亏我一开始还多写了👀️ )
最后提醒大家一定不要看错数据范围,我一开始看到了50%那里把N赋成了1e4👀️ 后来RE了排查半天才改过来👀️
- 1
信息
- ID
- 668
- 时间
- 500ms
- 内存
- 125MiB
- 难度
- 7
- 标签
- 递交数
- 269
- 已通过
- 58
- 上传者