• [ZONe Energy Programming Contest C] MAD TEAM


    前言

    这里有一个不太优秀但是很好打的做法。

    先说时间复杂度:(O(frac{25}{2}N^2))。如果想看更优时间复杂度,请移步木示木干的博客。

    题目

    AtCoder

    题目大意:

    (N) 个人,每个人有五个能力值 (A_i,B_i,C_i,D_i,E_i),我们要从中选出三个人成为一个组,一个组中一种能力的能力值定义为所有人该种能力的最大值,一个组的能力值定义为该组五种能力值的最小值。

    选出一个组使得其能力值最大并输出之。

    (3le N le 3000, 1le A_i,B_i,C_i,D_i,E_ile 10^9)

    讲解

    由于有五种能力,三个人,我们考虑谁可以成为这个团队各个能力的顶梁柱,对该能力有贡献,也就是该种能力的最大值。

    根据鸽巢原理,至少其中一个人对于该组的贡献至多有一种能力,而其余能力由另外两人贡献。所以我们就直接枚举两个人,再枚举另一个人对改组贡献的能力是哪一种,选择最大的即可。

    当然,这样的实现方式有很多,我选择了最好写的排序找最大值。

    注意在找最大值的时候不要与前面的人重复了。

    代码

    考场代码确实比较丑,见谅。

    //12252024832524
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define TT template<typename T>
    using namespace std; 
    
    typedef long long LL;
    const int MAXN = 3005;
    const LL INF = (1ll << 60);
    int n,now;
    LL ans;
    
    LL Read()
    {
    	LL x = 0,f = 1;char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    struct node
    {
    	LL a[5],ID;
    }s[6][MAXN];
    bool cmp(node x,node y)
    {
    	return x.a[now] > y.a[now];
    }
    void update(node A,node B,node C)
    {
    	LL ret = INF;
    	for(int i = 0;i < 5;++ i)
    		ret = Min(ret,Max(A.a[i],Max(B.a[i],C.a[i])));
    	ans = Max(ans,ret);
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read();
    	for(int i = 1;i <= n;++ i)
    		for(int j = 0;j < 5;++ j)
    		{
    			s[0][i].a[j] = Read();
    			s[0][i].ID = i;
    			for(int k = 1;k < 6;++ k) s[k][i].a[j] = s[0][i].a[j],s[k][i].ID = i;
    		}
    	for(now = 0;now < 5;++ now) sort(s[now]+1,s[now]+n+1,cmp);
    	for(int i = 1;i <= n;++ i)
    		for(int j = i+1;j <= n;++ j)
    			for(int k = 0;k < 5;++ k)
    				for(int l = 1;l <= 3;++ l)
    				{
    					if(s[k][l].ID != i && s[k][l].ID != j)//不要重复了
    					{
    					    update(s[5][i],s[5][j],s[k][l]);
    					    break;
    					}	
    				}
    	Put(ans);
    	return 0;
    }
    
  • 相关阅读:
    关于工作中Git相关的总结
    浅谈MySQL的优化
    由内搜推送思考Kafka 的原理
    SOA和微服务架构
    Centos7.2 搭建Lamp服务器以及迁移WordPress个人博客详细过程
    MyISAM和InnoDB索引实现区别
    图解高内聚与低耦合
    图解Java常用数据结构(一)
    Java源码安全审查
    Java高并发之锁优化
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14725311.html
Copyright © 2020-2023  润新知