1199: [HNOI2005]汤姆的游戏 - BZOJ
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万,顿时崩溃了,改完就过了
const
eps=1e-7;
type
extended=double;
var
cx,cr,cy:array[..]of extended;
lx,ly,rx,ry:array[..]of extended;
ans,k:array[..]of longint;
x,y:array[..]of extended;
n,m,numr,numc:longint; procedure swap(var x,y:extended);
var
t:extended;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint);
var
i,j,t:longint;
z:extended;
begin
i:=l;
j:=r;
z:=x[(l+r)>>];
repeat
while z>x[i]+eps do
inc(i);
while x[j]>z+eps do
dec(j);
if i<=j then
begin
swap(x[i],x[j]);
swap(y[i],y[j]);
t:=k[i];k[i]:=k[j];k[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end; procedure init;
var
i:longint;
s:char;
begin
read(n,m);
for i:= to n do
begin
read(s);
while (s<>'r')and(s<>'c') do
read(s);
if s='r' then
begin
inc(numr);
read(lx[numr],ly[numr],rx[numr],ry[numr]);
if lx[numr]>rx[numr] then swap(lx[numr],rx[numr]);
if ly[numr]>ry[numr] then swap(ly[numr],ry[numr]);
end
else
begin
inc(numc);
read(cx[numc],cy[numc],cr[numc]);
end;
end;
for i:= to m do
read(x[i],y[i]);
for i:= to m do
k[i]:=i;
sort(,m);
end; procedure work;
var
i,j,ll,rr,left,right,mid:longint;
begin
for i:= to numc do
begin
left:=;right:=m;
while left<right do
begin
mid:=(left+right)>>;
if x[mid]>cx[i]-cr[i] then right:=mid
else left:=mid+;
end;
ll:=left;
left:=;right:=m;
while left<right do
begin
mid:=(left+right+)>>;
if cx[i]+cr[i]>x[mid] then left:=mid
else right:=mid-;
end;
rr:=right;
for j:=ll to rr do
if sqr(cr[i])-eps>sqr(x[j]-cx[i])+sqr(y[j]-cy[i]) then inc(ans[k[j]]);
end;
for i:= to numr do
begin
left:=;right:=m;
while left<right do
begin
mid:=(left+right)>>;
if x[mid]>lx[i] then right:=mid
else left:=mid+;
end;
ll:=left;
left:=;right:=m;
while left<right do
begin
mid:=(left+right+)>>;
if rx[i]>x[mid] then left:=mid
else right:=mid-;
end;
rr:=right;
for j:=ll to rr do
if (y[j]>ly[i]+eps)and(ry[i]>y[j]+eps)and(x[j]>lx[i]+eps)and(rx[i]>x[j]+eps) then inc(ans[k[j]]);
end;
for i:= to m do
writeln(ans[i]);
end; begin
init;
work;
end.
pascal代码
#include<cstdio>
#include<algorithm>
using namespace std; typedef double ld; const int maxn=;
const int maxm=;
const ld eps=1e-; 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=;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=;i<=m;++i)
{
scanf("%lf%lf",&d[i].x,&d[i].y);
d[i].k=i;
}
sort(d+,d+m+);
int left,right,ll,rr,mid;
for(i=;i<=numr;++i)
{
left=,right=m;
while(left<right)
{
mid=(left+right)/;
if(d[mid].x>rec[i].lx)right=mid;
else left=mid+;
}
ll=left;
left=;right=m;
while(left<right)
{
mid=(left+right+)/;
if(d[mid].x<rec[i].rx)left=mid;
else right=mid-;
}
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=;i<=numc;++i)
{
left=;right=m;
while(left<right)
{
mid=(left+right)/;
if(d[mid].x>cir[i].x-cir[i].r)right=mid;
else left=mid+;
}
ll=left;
left=;right=m;
while(left<right)
{
mid=(left+right+)/;
if(cir[i].x+cir[i].r>d[mid].x)left=mid;
else right=mid-;
}
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=;i<=m;++i)
printf("%d\n",ans[i]);
return ;
}
C++代码
1199: [HNOI2005]汤姆的游戏 - BZOJ的更多相关文章
- BZOJ 1199: [HNOI2005]汤姆的游戏 计算几何暴力
1199: [HNOI2005]汤姆的游戏 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- 洛谷 P2313 [HNOI2005]汤姆的游戏 题解
P2313 [HNOI2005]汤姆的游戏 题目描述 汤姆是个好动的孩子,今天他突然对圆规和直尺来了兴趣.于是他开始在一张很大很大的白纸上画很多很多的矩形和圆.画着画着,一不小心将他的爆米花弄撒了,于 ...
- 几何【P2313】 [HNOI2005]汤姆的游戏
顾z 你没有发现两个字里的blog都不一样嘛 qwq 题目描述--->p2313 [HNOI]汤姆的游戏 分析 说不上是分析. 数据范围给出来,这题明显暴力啊emmm. 个人认为的坑点. 这题不 ...
- P2313 [HNOI2005]汤姆的游戏
题目描述 汤姆是个好动的孩子,今天他突然对圆规和直尺来了兴趣.于是他开始在一张很大很大的白纸上画很多很多的矩形和圆.画着画着,一不小心将他的爆米花弄撒了,于是白纸上就多了好多好多的爆米花.汤姆发现爆米 ...
- bzoj千题计划176:bzoj1199: [HNOI2005]汤姆的游戏
http://www.lydsy.com/JudgeOnline/problem.php?id=1199 求出圆x的范围 把要判断的点按x从小到大排序 枚举图形 二分出x满足这个图形的一段区间 枚举这 ...
- [HNOI2005]汤姆的游戏
嘟嘟嘟 直接O(n ^ 2)暴力判断就行了. 对于圆,判断该点和圆心的距离是否小于半径. 然而为啥我这么写编译不过: scanf("%lf%lf%lf%lf", &a[++ ...
- 汤姆大叔 javascript 系列 第20课 最后的5到javascript题目
博客链接:http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html 原题: 大叔注:这些题目也是来自出这5个题目的人,当然如果你能答对4 ...
- 你必须知道ASP.NET知识------关于动态注册httpmodule(对不起汤姆大叔)
一.关于动态注册的问题 很多人看过汤姆大叔的MVC之前的那点事儿系列(6):动态注册HttpModule ,其实汤姆大叔没有发现httpmodule动态注册的根本机制在哪里. 亦即:怎么动态注册?为什 ...
- 我读汤姆大叔的深入理解js(二)
继续汤姆大叔的js之旅. 揭秘命名函数表达式 函数表达式和函数声明 汤姆大叔在博客中引用ECMA规范:函数声明必须带有标识符,函数表达式可以省略.对于我来说这些概念的东西真是不所适从.还是大叔的实例带 ...
随机推荐
- C# 学习笔记01
想写一个app可以访问数据库,实现对数据库的查询,修改等,突然发现知识实在有限,故选择C#来实现此app. 使用简单的三层架构来作为此app的架构.表现层(UI).业务逻辑层(BLL).数据访问层(D ...
- VSX规划Package文件
VSX是VS扩展,可以针对不同项目编写插件,虽然接触VSX的时间并不多,但是当了解VSX后深刻感受到VSX的魅力. VSX的材料比较少,配置文件也很繁琐,当初我也走了不少弯路. 这篇文章将帮助您更好的 ...
- 在Ubuntu中USB连接手机调试
1.打开手机USB调试功能 显示“开发者选项”(开发者选项默认隐藏,一般需要进入到“设置”-->“关于手机”连续点击七次,可将“开发者选项显示出来”) 将“开发者选项”设置为“开启”状态 打开U ...
- Java之绘制艺术图案
前面已经介绍过绘制方法.这里不再赘述. package com.caiduping; import java.awt.Color; import java.awt.Graphics; import j ...
- Sql Server Profiler跟踪死锁
Sql Server Profiler一个很重要的应用场景就是监视分析死锁. 下面通过一个例子来学习Profiler是如何监视死锁的. 1. 创建测试数据模拟死锁, 创建表Table_A和Table_ ...
- 第三篇、微信小程序-网络请求API
wx.request(OBJECT)发起的是https请求.一个微信小程序,同时只能有5个网络请求连接. OBJECT参数说明: 效果图: net.js Page({ data:{ result:{} ...
- JqGrid在IE8中表头不能分组的解决办法
修改JqGrid的js脚本: for (d = 0; d < c; d++) { if (b[d] != undefined) { //主要是添加这个判断 if (b[d].startColum ...
- 【解惑】深入jar包:从jar包中读取资源文件
[解惑]深入jar包:从jar包中读取资源文件 http://hxraid.iteye.com/blog/483115 TransferData组件的spring配置文件路径:/D:/develop/ ...
- DTCMS清除 &
DTcms.Common\Utils.cs #region 清除HTML标记 public static string DropHTML(string Htmlstring) 中的 Htmlstrin ...
- preventDefault()、stopPropagation()、return false 之间的区别
“return false”之所以被误用的如此厉害,是因为它看起来像是完成了我们交给它的工作,浏览器不会再将我们重定向到href中的链接,表单也不会被继续提交,但这么做到底有什么不对呢? 可能在你刚开 ...