刚打完ABC接着要打div2,看到第一题第一时间没想过来就不打算下场了,后续补题发现,其实前三题都比较简单
补题
A
题面
爱丽丝邀请她的朋友参加一个聚会吃蛋糕。然而,每个朋友可能不在同一个地方,所以大家必须先在同一个地点见面。
Alice 有 n 个朋友,其中第 i 个朋友位于位置 ai 。为了让每个人都在同一个地方,Alice 必须进行多次群组通话。不幸的是,信号很弱,Alice 一次只能呼叫 2 其他人。
作为一个好人,爱丽丝不希望她的朋友走太远。因此,对于包含第 i 个朋友和第 j 个朋友的每个群组通话,Alice 会告诉他们两个在 min(ai,aj) 和 max(ai,aj) (含)之间的某个整数位置见面。之后,他们两人都会快速移动到该位置,以至于Alice在移动过程中无法进行任何群组通话。请注意,一旦这些朋友到达该位置,爱丽丝就可以再次呼叫他们。
聚会即将开始,Alice 需要快速进行群组通话。帮助她找到需要拨打的最少群组通话次数。
思路:
要将所有人聚在一起,而朋友i和朋友j可以通过一次操作瞬移到两人之间的某个位置,即Ai和Aj之间的任意一个位置。那么我们将A排序,将最远的两人往中间瞬移,不断操作,直至所有人都到一起为止。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void sol() { int N; cin>>N; for(int i=1;i<=N;i++) { cin>>a[i]; } sort(a+1,a+N+1); int ans=0; int l=1,r=N; while(a[l]!=a[r]) { ans++; l++; r--; if(l>N/2)break; } cout<<ans<<'\n'; }
|
B
题面
爱丽丝正在为她的聚会准备蛋糕。然而,她太匆忙了,所以蛋糕上的糖霜不均匀。为了快速解决这个问题,爱丽丝会将她的刀放在某个整数高度,然后从左到右扫过糖霜以使糖霜平整。
正式地,令 ai 为第 i 个位置处的糖霜高度。假设爱丽丝将她的刀放在某个整数高度 h 。如果位置 i 处的糖霜高度大于 h ,则多余的糖霜将被推至位置 i+1 。 n 位置上多余的糖霜将完全从蛋糕上脱落。
爱丽丝和她的朋友们非常喜欢蛋糕糖霜。由于 Alice 可能决定提供蛋糕的某些前缀而不是整个蛋糕,因此请帮助她找到糖霜的最大高度,同时保持 i=1,2,…,n 的前 i 位置的糖霜水平。
分析:
假设取出前i个糖霜用刀扫平后最大高度为h,那么处理前i+1个糖霜时:
- 如果Ai+1>Ai,那么Ai+1必须被抹平到h。
- 如果Ai+1≤Ai,那么就可以将前面的蛋糕平摊给Ai+1,此时h′=⌊i+11∑i+1Ak⌋,多余的被丢弃。
由此也可以发现最后的答案一定是个非递增序列。
思路:
只需要维护一个前缀和sum,如果加上Ai后,均值⌊isum⌋增大,则答案不变,反之答案变小,因此每次取ansi=min(ansi−1,⌊isum⌋)即可。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void sol() { int n; cin>>n; int sum=0,ans=MAX; for(int i=1;i<=n;i++) { cin>>a[i]; sum+=a[i]; ans=min(ans,sum/i); cout<<ans<<' '; } cout<<'\n'; }
|
C
题面
爱丽丝的朋友们来参加聚会了,现在他们正在排队参加聚会。
聚会上有 x 张桌子,每张桌子有 s 个座位。每个座位只能容纳一个人。
每个朋友都具有以下三种性格之一:
- 必须坐在空桌子旁的内向者 (I)
- 必须坐在非空桌子旁的外向者 (E)
- 中间性格者 (A) 可以坐在任何桌子上。
最初,每个座位都是空的。然而,由于爱丽丝正在吃蛋糕,她的朋友们已经排好了队,爱丽丝无法改变他们的顺序。对于队列中的每个人,爱丽丝必须为他们分配一张桌子或将他们踢出队伍。每个人就座后,下一个人就被分配到一张桌子。
为了在聚会上玩得开心,爱丽丝需要在聚会上容纳尽可能多的人。帮助她找到参加聚会的最多朋友数量。
请注意,一旦朋友入座,即使不再按照其性格入座,也不得再移动。
分析:
由于排队顺序无法改变,而每个人权重相同,不分贵贱,因此我们依次贪心地处理每个人,能入座就入座,并且在一定情况下,我们可以通过合理修改已入座人的位置,从而让更多地人入座。(反悔贪心)
- 对于A人,他可以随便坐,因此我们就要安排他入座,哪怕后续导致I人实在无法入座,但由于均只对贡献了1,我们可以舍弃这个I人。
- 对于E人,他必须坐在有人的桌子上。那么他需要有A人或I人为他“开辟”一张桌子,才能入座。
- E人无法入座的条件为已有人的桌子坐满了人且没有足够的A人和I人为他开辟桌子。
- 对于I人,他必须坐在没有人的桌子上。因此我们需要尽量让A人和E人占据的桌子更少,从而让I人入座。
- I人无法入座的条件为没有无人桌子。(在A人和E人占据最少桌子时)
思路:
通过以上分析,我们需要统计入座人数sum。
因为E人入座需要判断是否有足够多的A人和I人,因此我们要统计入座A人数sumA,入座I人数sumE。(当然二者可以合并)
我们需要尽可能压缩A人和E人的空间,因此我们一个桌子一个桌子地处理,只有在必要情况下我们才去开辟下一个桌子,记录坐到了第icnt个桌子。
由此我们可以知道有人桌子中最多可以坐icnt×s个人。
最多可以开辟sumA+sumI张桌子。
再结合上述贪心思想,便可以通关本题。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| void sol() { int n,x,s; cin>>n>>x>>s; int icnt=0; string S; cin>>S; int sum=0,sumA=0,sumI=0; for(auto i=0u;i<S.size();i++) { char c=S[i]; if(c=='A') { if(icnt*s>sum) { sumA++; sum++; } else { if(icnt<x) { sumA++; sum++; icnt++; } } } if(c=='E') { if(icnt*s>sum) { sum++; } else { if(icnt<x&&sumA+sumI>icnt) { icnt++; sum++; } } } if(c=='I') { if(icnt<x) { icnt++; sumI++; sum++; } } } cout<<sum<<'\n'; }
|