The Trip, 2007 UVA - 11100

问题

https://vjudge.net/problem/UVA-11100

分析

开始的错误做法:没有看英文题目,直接看的中文,结果漏了重要信息
While maintaining the minimal number of pieces you
are also to minimize the total number of bags in any one piece that must be carried.
这是要求在分的包的数量最小时,最大的包里面装的东西也应该最小,就是要尽量平均装。
下面是错的:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=10000+5,Inf=0x3f3f3f3f;
int d[maxn],num[maxn],m[maxn],cnt,n,kase=0;
int main(void){
    while(scanf("%d",&n)==1 && n){
        for(int i=1;i<=n;++i){
            scanf("%d",&d[i]);
        }
        sort(d+1,d+n+1);
        cnt=0;
        int ans=0;
        for(int i=1;i<=n;++i){
            if(d[i]!=d[i-1]){
                ++cnt;
                num[cnt]=0;
                m[cnt]=d[i];
            }
            ++num[cnt];
            ans=max(ans,num[cnt]);
        }
        printf("%d\n",ans);
        for(int i=0;i<ans;++i){
            int ok=1;
            for(int j=1;j<=cnt;++j){
                if(num[j]){
                    if(ok){
                        ok=0;
                        printf("%d",m[j]);
                    }else printf(" %d",m[j]);
                    --num[j];
                }
            }
            printf("\n");
        }
    }
    return 0;
}

参考别人的做法,类似于等差数列,先将1-k作为k个首元素,然后按照k的间隔取下一个,这样就将序列均分为k份,而且子序列间没有重复,并且每个子序列都是递增的序列,很巧妙的方式
https://blog.csdn.net/lycommand/article/details/50491955

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=10000+5,Inf=0x3f3f3f3f;
int d[maxn],n,kase=0;
int main(void){
    while(scanf("%d",&n)==1 && n){
        for(int i=1;i<=n;++i){
            scanf("%d",&d[i]);
        }
        d[0]=-Inf;
        sort(d+1,d+n+1);
        int ans=0,t=0;
        for(int i=1;i<=n;++i){
            if(d[i]==d[i-1]){
                ++t;
            }else{
                ans=max(ans,t);
                t=1;
            }
        }
        ans=max(ans,t);
        printf("%d\n",ans);
        for(int i=1;i<=ans;++i){
            int ok=1;
            for(int j=i;j<=n;j+=ans){
                if(j>i) printf(" ");
                printf("%d",d[j]);
            }
            printf("\n");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值