20241031模拟赛题解

1|0T1

1|1题目描述

给定一个圆形蛋糕,被 n 条切割线分成 n 个扇形蛋糕块,按照顺时针编号,第 i 块上有 ai 个草莓,第 i 条切割线到第 i+1 条切割线之间的部分是第 i 块蛋糕。

Alice 和 Bob 流选择切割线,假设 Alice 选择了第 i 条切割线,Bob选择了第 j 条切割线,j 不能等于 i。则 Alice 获得从第 i 条切割线顺时针到第 j 条切割线之间的蛋糕,Bob获得剩余蛋糕。Alice 的平均草莓数若大于等于 Bob 的平均草莓数,则 Alice 获胜,否则 Bob 获胜。求使 Alice 必胜的最小切割线编号,不存在则输出 1

1|2输入格式

第一行一个正整数 n

第二行 n 个正整数 ai 表示第 i 块内的草莓数量。

1|3输出格式

一个整数,即为答案。

1|4样例

1|0样例输入1

3 3 8 5

1|0样例输出1

2

Alice 在 38 之间切一刀,Alice要么会拿到 8 要么会拿到 85,都可以获胜。

1|5数据范围

对于所有数据 1<n500000,1ai500000

对于 50% 的数据 n1000

对于 100% 的数据无特殊限制。

1|6解法说明

可将每个 ai 转化为其与所有数字的平均值之间的差,对新的 ai 做前缀和,则当 Alice 选 i,Bob 选 j 时,如 sumj1sumi10,则 Alice 胜。故 Alice 应选 sumi1 最小的点后面的切割线,此时无论 Bob 如何选择都必败。

1|7通过代码

#include<bits/stdc++.h> using namespace std; #define int long long const int N=5e5+10; namespace IO{ inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') f=(ch=='-'?-1:f),ch=getchar(); while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return x*f; } inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } }using namespace IO; namespace code{ int n,a[N],sum[N],ans; void solve(){ n=read(); for(int i=1;i<=n;i++) a[i]=read(),sum[i]=sum[i-1]+a[i]; for(int i=1;i<=n;i++) a[i]=a[i]*n-sum[n]; for(int i=1;i<n;i++) sum[i]=sum[i-1]+a[i],ans=(sum[i]<sum[ans]?i:ans); write(ans+1); } } signed main(){ code::solve(); return 0; }

2|0T2

2|1题目描述

游乐园有 n 个项目,第 i 个项目直接排队要 ai 分钟,使用优速通需要排队 bi 分钟。你有 k 张优速通票,也就是意味着你可以选不超过 k 个项目使用优速通。你一共有 t 分钟,这里忽略除了排队以外的其他时间。你想知道你最多可以玩多少个不同的项目。

2|2输入格式

第一行三个正整数 nkt

接下来 n 行,每行两个正整数 aibi

2|3输出格式

一个整数,即最多能玩的项目数量。

2|4样例

1|0样例输入1

5 2 20 7 4 10 8 3 3 8 7 9 5

1|0样例输出1

4

2|5数据范围

对于所有数据 1kn2×105,1T1018,1biai1012

对于 20% 的数据:n10

对于 50% 的数据:n1000

对于 100% 的数据:无特殊限制。

2|6解法说明

反悔贪心。

显然,前 k 个肯定是 bi 能选几个是几个。如果选完后 t>0,则应增加一些项目,有以下两种可能:

  1. 新加一个 ai
  2. 新加一个 bi,并将一个选过的 bj 换成 aj

此时我们可以开三个堆,一个存储未选过的 ai,另一个存储未选过的 bi,最后一个存储选过的 ajbj。记三个堆堆顶分别为 uvw,则如果 u<v+w 选择第一种,否则选择第二种,不停循环直到 t<0 为止。

2|7通过代码

#include<bits/stdc++.h> using namespace std; #define int long long #define PII pair<int,int> #define mp make_pair const int N=2e5+10; namespace IO{ inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') f=(ch=='-'?-1:f),ch=getchar(); while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return x*f; } inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } }using namespace IO; namespace code{ int n,k,t,ans; bool vis[N]; struct node{ int a,b; }a[N]; priority_queue<PII,vector<PII>,greater<PII> > q1,q2,q3; bool cmp(node x,node y){ return x.b<y.b; } void solve(){ n=read(),k=read(),t=read(); for(int i=1;i<=n;i++) a[i].a=read(),a[i].b=read(); sort(a+1,a+n+1,cmp); for(int i=1;i<=k&&t>=0;i++,ans++) t-=a[i].b,vis[i]=1; if(t<0) return write(ans-1),void(); for(int i=1;i<=n;i++){ if(!vis[i]) q1.push(mp(a[i].a,i)),q2.push(mp(a[i].b,i)); else q3.push(mp(a[i].a-a[i].b,i)); } while(t>0){ int x=q1.top().second,y=q2.top().second,u,v,w; while(vis[x]) q1.pop(),x=q1.top().second; while(vis[y]) q2.pop(),y=q2.top().second; ans++,u=q1.top().first,v=q2.top().first,w=q3.top().first; if(u<v+w) q1.pop(),vis[x]=1,t-=u; else q2.pop(),q3.pop(),vis[y]=1,t-=v+w,q3.push(mp(a[y].a-a[y].b,y)); } write(t<0?--ans:ans); } } signed main(){ code::solve(); return 0; }

__EOF__

本文作者Alexxtl
本文链接https://www.cnblogs.com/Alexxtl/p/18518466.html
关于博主:I am a good person
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Alexxtl  阅读(87)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示