JOJ 2442: Be efficient 线段树的做法

2442: Be efficient


ResultTIME LimitMEMORY LimitRun TimesAC TimesJUDGE
3s8192K876147Standard

Given a triangle and the length of its edges,we could calculate its area easily. But the task is complicated by that given lots of triangles and several intervals represented by two numbers i and j (which means from triangle i to triangle j both inclusive),how could we determine which triangle in interval holds the largest area as fast as we can?

Input

There are several cases .In each case,the first line is two integer K(0 < K < 50000) and N(0 < N < 1000). K represent the number of trangles. The following K lines each contains 3 positive integers (a,b,c) means length of three edges.If a,b and c cannot form a triangle,then the area is zero. The next following N lines each contains 2 positive integers means the begin and the end of intervals.

Output

three edges of the largest triangle in each given interval.If area of the largest triangle is 0,output "I don't know~!". Order of edges is the same as input.output a blank line after each cases.

Sample Input

6 4
3 4 5
4 5 6
7 4 5
1 2 3
11 22 20
7 7 7
1 2
3 4
4 4
1 6

Sample Output

4 5 6
7 4 5
I don't know~!
11 22 20


Note

If there are severl triangles with the same largest area, you should output the first one.

 

Problem Source: slp3

 


This problem is used for contest: 95 


Submit / Problem List / Status / Discuss

 

 

时间很快,可内存占用比较多,还是可以的

#include<stdio.h>

#include<math.h>

#define LL(x)  (x<<1)

#define RR(x) (x<<1|1)

 

struct Seg_Tree

{

    int left,right,num;

    int calmid() { return (right+left)/2;}

}tree[120020];

 

struct node

{

    int x,y,z;

    double value;

} num[50010];

 

int build(int left,int right,int idx)

{

    tree[idx].left=left;

    tree[idx].right=right;

    if(left==right)

    {

         return tree[idx].num=left;

    }

    int mid=tree[idx].calmid();

    int x=build(left,mid,LL(idx));

    int y=build(mid+1,right,RR(idx));

    if(num[x].value>num[y].value) return tree[idx].num=x;

    else return tree[idx].num=y;

}

 

int query(int left,int right,int idx)

{

    if(left<=tree[idx].left && right>=tree[idx].right) return tree[idx].num;

    int mid=tree[idx].calmid();

    if(right<=mid)  return query(left,right,LL(idx));

    else if(left>mid)  return query(left,right,RR(idx));

    else

    {

        int x=query(left,mid,LL(idx));

        int y=query(mid+1,right,RR(idx));

        if(num[x].value>num[y].value)   return x;

        else return y;

    }

}

int fabs(int c)

{

    if(c<0) return -c;

    return c;

}    

 

bool check(int a,int b,int c)

{

    if( a+b>c && a+c>b && b+c>a && fabs(a-b)<c && fabs(a-c)<b && fabs(b-c)<a)  return true;

    return  false;

}

double triangle(int a,int b,int c)

{

    double p=(a+b+c)*1.0/2;

    double s=sqrt(p*(p-a)*(p-b)*(p-c));

    return s;

}

int main()

{

    int k,n,a,b;

    while(scanf("%d%d",&k,&n)!=EOF)

    {

        for(int i=1;i<=k;i++)

        {

           scanf("%d%d%d",&num[i].x,&num[i].y,&num[i].z);

           if(check(num[i].x,num[i].y,num[i].z))

                   num[i].value=triangle(num[i].x,num[i].y,num[i].z);

           else  num[i].value=0;

        }

        build(1,k,1);

        for(int i=1;i<=n;i++)

        {

            scanf("%d%d",&a,&b);

            int xx=query(a,b,1);

            if(num[xx].value!=0)   printf("%d %d %d/n",num[xx].x,num[xx].y,num[xx].z);

            else printf("I don't know~!/n");

        }

        printf("/n");

    }

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值