1199: [HNOI2005]汤姆的游戏 - BZOJ
2014-03-11 17:45
260 查看
Description
汤姆是个好动的孩子,今天他突然对圆规和直尺来了兴趣。于是他开始在一张很大很大的白纸上画很多很多的矩形和圆。画着画着,一不小心将他的爆米花弄撒了,于是白纸上就多了好多好多的爆米花。汤姆发现爆米花在白纸上看起来就像一个个点,有些点落在矩形或圆内部,而有些则在外面。于是汤姆开始数每个点在多少个矩形或圆内部。毕竟汤姆还只是个孩子,而且点、矩形和圆又非常多。所以汤姆数了好一会都数不清,于是就向聪明的你求助了。你的任务是:在给定平面上N个图形(矩形或圆)以及M个点后,请你求出每个点在多少个矩形或圆内部(这里假设矩形的边都平行于坐标轴)。
Input
第一行为两个正整数N和M,其中N表示有多少个图形(矩形或圆),M表示有多少个点。接下来的N行是对每个图形的描述,具体来说,第i+1行表示第i个图形。先是一个字母,若该字母为“r”,则表示该图形是一个矩形,这时后面将有4个实数x1,y1,x2,y2,表示该矩形的一对对角顶点的坐标分别为(x1,y1)和(x2,y2);若该字母为“c”,则表示该图形是一个圆,这时后面将有3个实数x,y,r,表示该圆以(x,y)为圆心并以r为半径。最后M行是对每个点的描述,其中每行将有两个实数x,y,表示一个坐标为(x,y)的点。
Output
包含M行,每行是一个整数,其中第i行的整数表示第i个点在多少个图形内部(当某点在一个图形的边界上时,我们认为该点不在这个图形的内部)。
Sample Input
3 4
r 1.015 0.750 5.000 4.000
c 6.000 5.000 2.020
r 6.500 7.200 7.800 9.200
3.500 2.500
4.995 3.990
2.300 8.150
6.900 8.000
Sample Output
1
2
0
1
好吧,写了很久,最后发现数组越界了(第20组n是20万,第18组就是25万,我只看了第20组数据.....谁叫他题目不写清楚,只能自己下数据了)
看了网上的C++程序,知道做法了
先将点按x坐标排序,再二分出有效区间即x坐标在矩形两个横坐标之间,或者在(x-r,x+r)之间的点,然后暴力是否被覆盖,统计答案
因为最开始那个问题,我还到处问人,去贴吧问,最后在我写完C++程序(照着网上的代码写)的时候发现n最大有25万,顿时崩溃了,改完就过了
C++代码
汤姆是个好动的孩子,今天他突然对圆规和直尺来了兴趣。于是他开始在一张很大很大的白纸上画很多很多的矩形和圆。画着画着,一不小心将他的爆米花弄撒了,于是白纸上就多了好多好多的爆米花。汤姆发现爆米花在白纸上看起来就像一个个点,有些点落在矩形或圆内部,而有些则在外面。于是汤姆开始数每个点在多少个矩形或圆内部。毕竟汤姆还只是个孩子,而且点、矩形和圆又非常多。所以汤姆数了好一会都数不清,于是就向聪明的你求助了。你的任务是:在给定平面上N个图形(矩形或圆)以及M个点后,请你求出每个点在多少个矩形或圆内部(这里假设矩形的边都平行于坐标轴)。
Input
第一行为两个正整数N和M,其中N表示有多少个图形(矩形或圆),M表示有多少个点。接下来的N行是对每个图形的描述,具体来说,第i+1行表示第i个图形。先是一个字母,若该字母为“r”,则表示该图形是一个矩形,这时后面将有4个实数x1,y1,x2,y2,表示该矩形的一对对角顶点的坐标分别为(x1,y1)和(x2,y2);若该字母为“c”,则表示该图形是一个圆,这时后面将有3个实数x,y,r,表示该圆以(x,y)为圆心并以r为半径。最后M行是对每个点的描述,其中每行将有两个实数x,y,表示一个坐标为(x,y)的点。
Output
包含M行,每行是一个整数,其中第i行的整数表示第i个点在多少个图形内部(当某点在一个图形的边界上时,我们认为该点不在这个图形的内部)。
Sample Input
3 4
r 1.015 0.750 5.000 4.000
c 6.000 5.000 2.020
r 6.500 7.200 7.800 9.200
3.500 2.500
4.995 3.990
2.300 8.150
6.900 8.000
Sample Output
1
2
0
1
好吧,写了很久,最后发现数组越界了(第20组n是20万,第18组就是25万,我只看了第20组数据.....谁叫他题目不写清楚,只能自己下数据了)
看了网上的C++程序,知道做法了
先将点按x坐标排序,再二分出有效区间即x坐标在矩形两个横坐标之间,或者在(x-r,x+r)之间的点,然后暴力是否被覆盖,统计答案
因为最开始那个问题,我还到处问人,去贴吧问,最后在我写完C++程序(照着网上的代码写)的时候发现n最大有25万,顿时崩溃了,改完就过了
#include<cstdio> #include<algorithm> using namespace std; typedef double ld; const int maxn=250010; const int maxm=10010; const ld eps=1e-7; int n,m,ans[maxm]; struct REC { ld lx,ly,rx,ry; }rec[maxn]; int numr; struct CIR { ld x,y,r; }cir[maxn]; int numc; struct point { ld x,y; int k; }d[maxm]; int operator < (const point & a,const point & b) { return a.x<b.x; } int main() { int i,j; scanf("%d%d",&n,&m); char s; for(i=1;i<=n;++i) { scanf("%s",&s); if(s=='r') { ++numr; scanf("%lf%lf%lf%lf",&rec[numr].lx,&rec[numr].ly,&rec[numr].rx,&rec[numr].ry); if(rec[numr].lx>rec[numr].rx) swap(rec[numr].lx,rec[numr].rx); if(rec[numr].ly>rec[numr].ry) swap(rec[numr].ly,rec[numr].ry); } else { ++numc; scanf("%lf%lf%lf",&cir[numc].x,&cir[numc].y,&cir[numc].r); } } for(i=1;i<=m;++i) { scanf("%lf%lf",&d[i].x,&d[i].y); d[i].k=i; } sort(d+1,d+m+1); int left,right,ll,rr,mid; for(i=1;i<=numr;++i) { left=1,right=m; while(left<right) { mid=(left+right)/2; if(d[mid].x>rec[i].lx)right=mid; else left=mid+1; } ll=left; left=1;right=m; while(left<right) { mid=(left+right+1)/2; if(d[mid].x<rec[i].rx)left=mid; else right=mid-1; } rr=right; for(j=ll;j<=rr;++j) if((d[j].x>rec[i].lx+eps)&(rec[i].rx>d[j].x+eps)&(d[j].y>rec[i].ly+eps)&(rec[i].ry>d[j].y+eps)) ++ans[d[j].k]; } for(i=1;i<=numc;++i) { left=1;right=m; while(left<right) { mid=(left+right)/2; if(d[mid].x>cir[i].x-cir[i].r)right=mid; else left=mid+1; } ll=left; left=1;right=m; while(left<right) { mid=(left+right+1)/2; if(cir[i].x+cir[i].r>d[mid].x)left=mid; else right=mid-1; } rr=right; for(j=ll;j<=rr;++j) if(cir[i].r*cir[i].r>(d[j].x-cir[i].x)*(d[j].x-cir[i].x)+(d[j].y-cir[i].y)*(d[j].y-cir[i].y)) ++ans[d[j].k]; } for(i=1;i<=m;++i) printf("%d\n",ans[i]); return 0; }
C++代码
相关文章推荐
- bzoj千题计划176:bzoj1199: [HNOI2005]汤姆的游戏
- BZOJ 1199 HNOI 2005 汤姆的游戏 计算几何
- 【BZOJ1199】【HNOI2005】汤姆的游戏 特技
- BZOJ 1199: [HNOI2005]汤姆的游戏 计算几何暴力
- BZOJ 1199: [HNOI2005]汤姆的游戏
- BZOJ 1199 HNOI2005 汤姆的游戏 计算几何+暴力
- bzoj1199: [HNOI2005]汤姆的游戏
- [HNOI2005]汤姆的游戏
- 几何【P2313】 [HNOI2005]汤姆的游戏
- [BZOJ1202][HNOI2005]狡猾的商人(并查集+前缀和)
- [bzoj1202][HNOI2005]狡猾的商人[并查集]
- 【BZOJ】1188 [HNOI2007]分裂游戏
- Bzoj1188 [HNOI2007]分裂游戏
- BZOJ 2000([Hnoi2010]stone 取石头游戏-贪心博弈)
- 【BZOJ1202】【HNOI2005】狡猾的商人
- [BZOJ1202][HNOI2005][并查集]狡猾的商人
- BZOJ 1202 [HNOI2005]狡猾的商人
- bzoj1202: [HNOI2005]狡猾的商人(并查集 差分约束)
- bzoj1202 [ HNOI2005 ] --带权并查集
- [BZOJ1202] [HNOI2005]狡猾的商人