uva 11012 - Cosmic Cabbages

Problem A
Cosmic Cabbages 
Input: 
Standard Input

Output: Standard Output

 

CABBAGE, n.
A familiar kitchen-garden vegetable about
as large and wise as a man's head.

Ambrose Bierce

Scientists from the planet Zeelich have figured out a way to grow cabbages in space. They have constructed a huge 3-dimensional steel grid upon which they plant said cabbages. Each cabbage is attached to a corner in the grid, where 6 steel cables meet and is assigned Cartesian coordinates. A cosmic ant wants to crawl from cabbage X to cabbage Y along the cables that make the grid. The cosmic ant always chooses the shortest possible path along the grid lines while going from cabbage X to cabbage Y. This distance is called the cosmic distance between two cabbages. Given a collection of cabbages what is the maximum distance between any two of the cabbages?

Input

The first line of input gives the number of cases, N (0<N<21)N test cases follow. Each one starts with a line containing n(2<=n<=105). The next n lines will each give the 3-dimensional coordinates of a cosmic cabbage (integers in the range[-108, 108]).

 

Output

For each test case, output one line containing "Case #x:" followed by the largest cosmic distance between cabbages X and Y, out of all possible choices of X and Y.

 

Sample Input                               Output for Sample Input

4

2

1 1 1

2 2 2

3

0 0 0

0 0 1

1 1 0

4

0 1 2

3 4 5

6 7 8

9 10 11

6

0 0 0

1 1 1

2 2 2

0 0 1

1 0 0

0 1 0

Case #1: 3

Case #2: 3

Case #3: 27

Case #4: 6

 

 


Problem setter: Igor Naverniouk, EPS

Special Thanks: Shahriar Manzoor, EPS

 

 

I liked this problem so much that I said to myself “If I were the problem setter of this problem?”

 n^2是不行的,我开始想到的方法是通过排序,减少每个点需要比较的点的个数。别人有一种更巧的方法是,枚举所有去掉绝对值后的情况。枚举8种情况,k1*x+k2*y+k3*z ,k取正负1。算出每种情况下,每个点对应的k1*x+k2*y+k3*z 值,找出这种情况时的 最大值Max,和最小值Min,ans = max(ans, Max-Min );最后的ans就是答案。对每一种情况下 用 Max-Min 得到的 不一定是那两个点间的距离,是小于等于,因为假如去绝对值的式子 应该是 x1-x2+y1-y2+z1-z2,而某种情况下的式子是 x2-x1+y1-y2+z1-z2,这个式子的值肯定小于前者,因为x2小于x1。然后因为 八种情况 覆盖了所有得到最大值的途径,所以求得的就是最大值。

贴了第一种方法的代码。

#include<cstdio>
#include<map>
#include<queue>
#include<cstring>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 100000 + 5;
const int INF = 1000000000;
typedef long long LL;
typedef pair<int, int> P;

struct Node{
    int x, y, z;
}a[maxn];

bool cmp1(Node a, Node b){
    return a.x+a.y+a.z < b.x+b.y+b.z;
}

bool cmp2(Node a, Node b){
    return a.x+a.y-a.z < b.x+b.y-b.z;
}

bool cmp3(Node a, Node b){
    return a.x-a.y+a.z < b.x-b.y+b.z;
}

bool cmp4(Node a, Node b){
    return -a.x+a.y+a.z < -b.x+b.y+b.z;
}

bool cmp5(Node a, Node b){
    return a.x-a.y-a.z < b.x-b.y-b.z;
}

bool cmp6(Node a, Node b){
    return -a.x+a.y-a.z < -b.x+b.y-b.z;
}

bool cmp7(Node a, Node b){
    return -a.x-a.y+a.z < -b.x-b.y+b.z;
}

bool cmp8(Node a, Node b){
    return -a.x-a.y-a.z < -b.x-b.y-b.z;
}

int main(){
    int t, kase = 0;
    scanf("%d", &t);
    while(t--){
        kase++;
        int n;
        scanf("%d", &n);
        for(int i = 0;i < n;i++){
            scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
        }
        int ans = 0;
        sort(a, a+n, cmp1);
        for(int i = 0;i < n;i++){
            for(int j = n-1;j >= 0;j--){
                if(a[j].x>a[i].x && a[j].y>a[i].y && a[j].z>a[i].z){
                    ans = max(ans, a[j].x-a[i].x+a[j].y-a[i].y+a[j].z-a[i].z);
                    break;
                }
            }
        }

        sort(a, a+n, cmp2);
        for(int i = 0;i < n;i++){
            for(int j = n-1;j >= 0;j--){
                if(a[j].x>a[i].x && a[j].y>a[i].y && a[j].z<a[i].z){
                    ans = max(ans, a[j].x-a[i].x+a[j].y-a[i].y-(a[j].z-a[i].z));
                    break;
                }
            }
        }

        sort(a, a+n, cmp3);
        for(int i = 0;i < n;i++){
            for(int j = n-1;j >= 0;j--){
                if(a[j].x>a[i].x && a[j].y<a[i].y && a[j].z>a[i].z){
                    ans = max(ans, a[j].x-a[i].x-(a[j].y-a[i].y)+a[j].z-a[i].z);
                    break;
                }
            }
        }

        sort(a, a+n, cmp4);
        for(int i = 0;i < n;i++){
            for(int j = n-1;j >= 0;j--){
                if(a[j].x<a[i].x && a[j].y>a[i].y && a[j].z>a[i].z){
                    ans = max(ans, -(a[j].x-a[i].x)+a[j].y-a[i].y+a[j].z-a[i].z);
                    break;
                }
            }
        }

        sort(a, a+n, cmp5);
        for(int i = 0;i < n;i++){
            for(int j = n-1;j >= 0;j--){
                if(a[j].x>a[i].x && a[j].y<a[i].y && a[j].z<a[i].z){
                    ans = max(ans, a[j].x-a[i].x-(a[j].y-a[i].y)-(a[j].z-a[i].z));
                    break;
                }
            }
        }

        sort(a, a+n, cmp6);
        for(int i = 0;i < n;i++){
            for(int j = n-1;j >= 0;j--){
                if(a[j].x<a[i].x && a[j].y>a[i].y && a[j].z<a[i].z){
                    ans = max(ans, -(a[j].x-a[i].x)+a[j].y-a[i].y-(a[j].z-a[i].z));
                    break;
                }
            }
        }

        sort(a, a+n, cmp7);
        for(int i = 0;i < n;i++){
            for(int j = n-1;j >= 0;j--){
                if(a[j].x<a[i].x && a[j].y<a[i].y && a[j].z>a[i].z){
                    ans = max(ans, -(a[j].x-a[i].x)-(a[j].y-a[i].y)+a[j].z-a[i].z);
                    break;
                }
            }
        }

        sort(a, a+n, cmp8);
        for(int i = 0;i < n;i++){
            for(int j = n-1;j >= 0;j--){
                if(a[j].x<a[i].x && a[j].y<a[i].y && a[j].z<a[i].z){
                    ans = max(ans, -(a[j].x-a[i].x+a[j].y-a[i].y+a[j].z-a[i].z));
                    break;
                }
            }
        }
        printf("Case #%d: %d\n", kase, ans);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值