题解 P4960 【血小板与凝血因子】
wjyyy
2018-11-04 07:53:36
>大家有发现赛后提交这个题的~~评测信息~~彩蛋吗
因为给出了两种容器,而且容器只能统一使用一种,因此一种比较暴力的方式是枚举这两种哪种更优。
实际上我们可以先对$a_i$排序,然后看出现了多少种不同的元素,元素的种类数是只使用容器$1$的答案,同种元素出现次数的最大值是容器$2$的答案。
比较上述两者答案,选择较小的。对容器$1$而言,答案就是每行把同种元素分为一组;对容器$2$而言,假设某种元素出现了$k$次,那么它出现且仅出现在第$1\sim k$组中。这样输出每组的元素数及元素即可,同时~~因为良心的spj writer~~可以不按顺序输出。
如果迭代器使用熟练的话,可以直接在`std::map`中统计答案并输出。
这道题主要考查了对数据的排序。在$n\le 1,000$的数据中,您可以使用任何可以想到的~~时间复杂度在O(n²logn)以内的~~排序方法来对$a_i$进行排序。
您甚至可以方便地使用`std::sort`、`std::map`来帮您减少代码复杂度,从而在这场ACM赛制的比赛中风生水起。
$\text{ctr}$相信,这道可爱又良心的题目,会让您的比赛之旅有一个好的~~1A~~开始,为您的AK之路提供有力的帮助。
## Code:
```cpp
#include<cstdio>
#include<map>
using std::map;
map<int,int> m;
int a[1010];
int ans[1010][1010];
int main()
{
int n,u;
scanf("%d",&n);
int mx=0;
for(int i=1;i<=n;++i)
{
scanf("%d",&u);
m[u]++;
mx=mx>m[u]?mx:m[u];
}
ans[0][0]=mx<m.size()?mx:m.size();
printf("%d ",ans[0][0]);
if(mx<m.size())
{
printf("%d\n",2);
for(map<int,int>::iterator it=m.begin();it!=m.end();++it)
{
int num=it->second;
for(int i=1;i<=num;++i)
ans[i][++ans[i][0]]=it->first;
}
for(int i=1;i<=ans[0][0];++i)
{
for(int j=0;j<=ans[i][0];++j)
printf("%d ",ans[i][j]);
puts("");
}
}
else
{
printf("%d\n",1);
for(map<int,int>::iterator it=m.begin();it!=m.end();++it)
{
int num=it->second;
printf("%d ",num);
for(int i=1;i<=num;++i)
printf("%d ",it->first);
puts("");
}
}
return 0;
}
```