Hdu-1823的题解
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1823
Problem Description
世界上上最远的距离不是相隔天涯海角
而是我在你面前
可你却不知道我爱你
―― 张小娴
前段日子,枫冰叶子给Wiskey做了个征婚启事,聘礼达到500万哦,天哪,可是天文数字了啊,不知多少MM蜂拥而至,顿时万人空巷,连扫地的大妈都来凑热闹来了。―_―|||
由于人数太多,Wiskey实在忙不过来,就把统计的事情全交给了枫冰叶子,自己跑回家休息去了。这可够枫冰叶子忙的了,他要处理的有两类事情,一是得接受MM的报名,二是要帮Wiskey查找符合要求的MM中缘分最高值。
而是我在你面前
可你却不知道我爱你
―― 张小娴
前段日子,枫冰叶子给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)
所有输入的浮点数,均只有一位小数。
接下来是一个操作符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。
对查找不到的询问,输出-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表示它)相互靠近。(单纯为了方便。。。@-@)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
还有就是自己的方法:直接找。常规方法之所以可行是因为它的范围不大,复杂度不够高。所以二分区间用线段树和直接找相差不是很大。。。
下面附上代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
如有任何问题欢迎指摘哦!!!