uva 11012 - Cosmic Cabbages

来源:互联网 发布:hadoop软件 编辑:程序博客网 时间:2024/05/22 05:32

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