题目意思:
给定n个包,现在每一个包的形状相同,但是大小不同。现在规定小号的包可以包含在大号里面。例如 4-3-2-1,现在给我们n个包,要我们求出最后需要的包是几个,还有尽量满足每一个最后包之间包含的小包的个数相同
解题思路:
1:思路:贪心
2:分析如下:
1首先我们知道相同大小的包是不能够包含在同一个大包里面的,所以最后需要的大包的个数就是原来序列中相同型号包的最大值
2 知道了最后需要的包的个数,那么就可以根据总的包个数n求出每个大包需要装的小包的个数
3 输出时候比较纠结了(题目明明说了任何一种输出都可以满足,但是它让我贡献了16个WA。我的思路是将n个包排完序后,假设现在需要ans个大包,那么在排完序后的数组中的前面ans个分别被分在不同的大包,然后只要按照求出的每一个大包的需要几个去求就可以了,discuss里面的样例都过了,尼玛就是WA啊,现在只能对天长叹"太不科学了"),看了队友的报告输出是用按照ans来等差输出。
4比如1 1 1 2 2 2 3 3 3 3 那么ans = 4 ,4个包所需的小包数为 3 3 2 2 。所以
第一个包:1 1 1 2 2 2 3 3 3 输出划线的三个 1 2 3
_ _ _
第二个包:1 1 1 2 2 2 3 3 3 输出划线的三个 1 2 3
_ _ _
.........
我觉得这个输出比我的更简单了,这个A了,为毛卧滴就WA了,不解中!
3:注意:题目要求每两个样例之间输出空行,我们一般用一个flag变量来标记,第一个样例之前不用输出空行,后面的则在输出之前输出一个空行,这样就可以避免了最后一组输出空行
代码:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; #define MAXN 10010 int n , ans , flag; int dim[MAXN];/*存储n个包的大小*/ int s[MAXN];/*存储大包包含的总的包的数量*/ void output(){ int i , j , tmp; if(!flag) printf("\n"); printf("%d\n" , ans); for(i = 0 ; i < ans ; i++){/*每一个大包的第一个小包*/ printf("%d" , dim[i]); for(j = 1 ; j < s[i] ; j++) printf(" %d" , dim[i+ans*j]);/*以ans为等差在数组中输出*/ printf("\n"); } } void solve(){ int i , pos , sum , tmp; /*排序找到最小的包的个数并且求出每一个包包含的个数*/ sort(dim , dim+n) ; pos = 0 ; sum = 1 ; ans = 0; for(i = 1 ; i < n ; i++){ if(dim[i] != dim[i-1]){ if(ans < sum) ans = sum ; sum = 1; } else sum++; } if(ans < sum) ans = sum ;/*这里也要注意更新*/ for(i = 0 , tmp = n/ans; i < ans ; i++) s[i]= tmp ; for(i = 0 , tmp = n%ans; i < tmp ; i++) s[i]++;/*于数的处理*/ } int main(){ //freopen("input.txt" , "r" , stdin); flag = 1; while(scanf("%d%*c" , &n) && n){ for(int i = 0 ; i < n ; i++) scanf("%d" , &dim[i]); solve() ; output(); if(flag) flag = 0; } return 0; }
迎大家纠正---双子座的等
待