题目意思:
给定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;
}
迎大家纠正---双子座的等
待