P4447分组

1|0一开始贪心思路不对且根本没考虑重复,无脑sort后直接排组玄学了70pts。

#include <iostream> #include <algorithm> using namespace std; int n; int cnt, ans = 0x7fffffff; int a[100010]; int main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } sort(a + 1, a + n + 1); for (int i = 2; i <= n; i++) { cnt++; if (a[i] - a[i - 1] > 1) { ans = min(ans, cnt); cnt = 0; } } if (a[n] - a[n - 1] > 1) { ans = min(1, ans); } if (ans == 0x7fffffff) { ans = n; } cout << ans; return 0; }

之后看了这位哥的题解,明白了正确的贪心思路。

通过桶思想存重复的数,然后类比俄罗斯方块消层来分组:
每次处理最底层,下一个相邻数的重复次数如果比上一个多,就划入组中,桶对应的计数器自减,如果下一个相邻数的重复次数比上一个少,就不划入组中。
联想俄罗斯方块,这种做法能尽可能地让上层齐平,从而使最少数量的组长度最大。

2|0代码实现

#include<map> #include<iostream> using namespace std; map<int,int> m; int ans = 0x7fffffff, n, temp; int main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> temp; ++m[temp]; } while(!m.empty()) { map<int, int>::iterator i = m.begin(), j = m.begin(); (*i).second--,j++,temp = 1; for (;j != m.end() && (*j).first == (*i).first + 1 && (*j).second > (*i).second; i++, j++) { temp++; (*j).second--; } i=m.begin(); while(i!=m.end()&&(*i).second==0){ m.erase((*i++).first); } ans = min(ans, temp); } cout << ans; return 0; }

__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/17783007.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示