Hdu-1823的题解

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1823

Problem Description
世界上上最远的距离不是相隔天涯海角
而是我在你面前
可你却不知道我爱你
                ―― 张小娴
前段日子,枫冰叶子给Wiskey做了个征婚启事,聘礼达到500万哦,天哪,可是天文数字了啊,不知多少MM蜂拥而至,顿时万人空巷,连扫地的大妈都来凑热闹来了。―_―|||
由于人数太多,Wiskey实在忙不过来,就把统计的事情全交给了枫冰叶子,自己跑回家休息去了。这可够枫冰叶子忙的了,他要处理的有两类事情,一是得接受MM的报名,二是要帮Wiskey查找符合要求的MM中缘分最高值。
Input
本题有多个测试数据,第一个数字M,表示接下来有连续的M个操作,当M=0时处理中止。
接下来是一个操作符C。
当操作符为‘I’时,表示有一个MM报名,后面接着一个整数,H表示身高,两个浮点数,A表示活泼度,L表示缘分值。 (100<=H<=200, 0.0<=A,L<=100.0)
当操作符为‘Q’时,后面接着四个浮点数,H1,H2表示身高区间,A1,A2表示活泼度区间,输出符合身高和活泼度要求的MM中的缘分最高值。 (100<=H1,H2<=200, 0.0<=A1,A2<=100.0)
所有输入的浮点数,均只有一位小数。
Output
对于每一次询问操作,在一行里面输出缘分最高值,保留一位小数。
对查找不到的询问,输出-1。
Sample Input
8
I 160 50.5 60.0
I 165 30.0 80.5
I 166 10.0 50.0
I 170 80.5 77.5
Q 150 166 10.0 60.0
Q 166 177 10.0 50.0
I 166 40.0 99.9
Q 166 177 10.0 50.0 0
Sample Output
80.5 50.0 99.9
题目思路:这是我在做线段树专题中碰到的一道题。用线段树的做法来做就是建立一个二维的线段树。横轴表示身高(下面代码的大K(1-100)),纵轴表示活泼度(代码中的小k(给每个节点二分(1-1000)活泼度的范围))。还有就是在更新的时候也要二维的更新(即对每一个横坐标对应的子树对应位置赋予缘分值)。然后在查询的时候只要按照横坐标依次对比出最大值即可。
另外,在建树的时候也有一些技巧。就是身高和活泼度尽量让他们的值(可以-100表示它)相互靠近。(单纯为了方便。。。@-@)
 1 #include"stdio.h"
 2 #include"string.h"
 3 #include"stdlib.h"
 4 struct Segtree
 5 {
 6     int l,r,mid;
 7     double max;
 8 }T[111][4*1011];
 9  
10 void build(int l,int r,int k,int K)//1,1000,1,i(0-100) 
11 {
12     T[K][k].l=l;
13     T[K][k].r=r;
14     T[K][k].mid=(l+r)>>1;
15     T[K][k].max=0;
16     if(l==r)    return ;
17     build(l,T[K][k].mid,2*k,K);
18     build(T[K][k].mid+1,r,2*k+1,K);
19 }
20 void update(int aim,int k,int K,double L)//10*a,1,h-100,l
21 {
22     if(T[K][k].l==aim && T[K][k].r==aim)
23     {
24         T[K][k].max=T[K][k].max>L?T[K][k].max:L;
25         return ;
26     }
27     if(aim<=T[K][k].mid)    update(aim,2*k,K,L);
28     else                    update(aim,2*k+1,K,L);
29     T[K][k].max=T[K][2*k].max>T[K][2*k+1].max?T[K][2*k].max:T[K][2*k+1].max;
30 }
31 double find(int l,int r,int k,int K)
32 {
33     double temp;
34     if(T[K][k].l==l && T[K][k].r==r)    return T[K][k].max;
35     if(r<=T[K][k].mid)        temp=find(l,r,2*k,K);
36     else if(l>T[K][k].mid)    temp=find(l,r,2*k+1,K);
37     else
38     {
39         double a,b;
40         a=find(l,T[K][k].mid,2*k,K);
41         b=find(T[K][k].mid+1,r,2*k+1,K);
42         temp=a>b?a:b;
43     }
44     return temp;
45 }
46 int main()
47 {
48     int n;
49     int i,l;
50     char str[10];
51     int a,b,c,d,t;
52     double f1,f2,f3,f4,t2;
53     double temp,ans;
54     while(scanf("%d",&n),n)
55     {
56         for(i=0;i<=100;i++)    build(0,1000,1,i);
57  
58         for(i=0;i<n;i++)
59         {
60             scanf("%s",str);
61             if(str[0]=='I')
62             {
63                 scanf("%d%lf%lf",&a,&f2,&f3);
64                 a-=100;
65                 update((int)(f2*10),1,a,f3);
66             }
67             else
68             {
69                 scanf("%d%d%lf%lf",&a,&b,&f3,&f4);
70                 if(a>b)        {t=a;a=b;b=t;}
71                 if(f3>f4)    {t2=f3;f3=f4;f4=t2;}
72                 a-=100;b-=100;
73                 ans=0;
74                 for(l=a;l<=b;l++)
75                 {
76                     temp=find((int)(f3*10),(int)(f4*10),1,l);
77                     if(temp>ans)    ans=temp;
78                 }
79                 if(ans==0)    printf("-1\n");
80                 else        printf("%.1lf\n",ans);
81             }
82         }
83     }
84     return 0;
85 }
View Code

还有就是自己的方法:直接找。常规方法之所以可行是因为它的范围不大,复杂度不够高。所以二分区间用线段树和直接找相差不是很大。。。

下面附上代码:

 1 //线段树专题j 
 2 #include<stdio.h>
 3 #include<string.h>
 4 #define INF 1000000+10
 5 struct P{
 6     int h;
 7     double a,l;
 8 }tree[INF];
 9 int main()
10 {
11     int m,cnt;double al,ar,hl,hr,l;char c;
12     while(~scanf("%d",&m)&&m)
13     {
14         cnt=0;double MAX;
15         for(int i=0,k=0;i<m;i++)
16         {
17             getchar();
18             scanf("%c",&c);
19             if(c=='I')
20             {
21                 scanf("%d%lf%lf",&tree[k].h,&tree[k].a,&tree[k].l);++cnt;k++;
22                 //printf("I=%d,t.h=%d,t.a=%lf,t.l=%lf\n",i,tree[i].h,tree[i].a,tree[i].l);
23             }
24             else if(c=='Q')
25             {
26                 scanf("%lf%lf%lf%lf",&hl,&hr,&al,&ar);
27                 if(hl>hr){
28                     MAX=hl;
29                     hl=hr;
30                     hr=MAX;
31                 }
32                 if(al>ar){
33                     MAX=al;
34                     al=ar;
35                     ar=MAX;
36                 }
37                 MAX=-1;
38                 for(int j=0;j<cnt;j++)
39                 {
40                     if(tree[j].h>=hl&&tree[j].h<=hr&&tree[j].a>=al&&tree[j].a<=ar&&MAX<tree[j].l)
41                     {
42                         MAX=tree[j].l;
43                     }
44                 }
45                 if(MAX==-1)
46                 {
47                     printf("-1\n");
48                 }
49                 else 
50                 {
51                     printf("%.1lf\n",MAX);
52                 }
53             }
54         }
55     }
56     return 0;
57 }
View Code

如有任何问题欢迎指摘哦!!!

posted @ 2019-03-16 21:53  Maynerd  阅读(203)  评论(0编辑  收藏  举报