using System;
using System.Collections.Generic;
namespace Hiho
{
class _124
{
struct Boundary
{
public int Up, Down, Left, Right;
public Boundary(int up, int down, int left, int right)
{
this.Up = up;
this.Down = down;
this.Left = left;
this.Right = right;
}
}
struct Range
{
public Point _Point;
public int R;
public Range(int x,int y,int r)
{
_Point.X = x;
_Point.Y = y;
R = r;
}
}
struct Point
{
public int X, Y;
}
class QuadtreeNode
{
public readonly int Capacity = 2000;
public Boundary Boundary;
public List<Point> points = new List<Point>();
public bool IsDivided = false;
public QuadtreeNode upleft = null;
public QuadtreeNode upright = null;
public QuadtreeNode leftbottom = null;
public QuadtreeNode rightbottom = null;
public QuadtreeNode(int up, int down, int left, int right)
{
this.Boundary.Up = up;
this.Boundary.Down = down;
this.Boundary.Left = left;
this.Boundary.Right = right;
}
private bool InBoundary(Point p, Boundary boundary)
{
if (p.Y <= boundary.Up && p.Y > boundary.Down && p.X < boundary.Right && p.X >= boundary.Left) //can't insert in right line and down line
return true;
return false;
}
private bool InBoundary(Point p, Range range)
{
double disSquare = (p.X - range._Point.X) * (p.X - range._Point.X) + (p.Y - range._Point.Y) * (p.Y - range._Point.Y);
if (disSquare <= range.R * range.R)
return true;
return false;
}
public void Insert(Point p)
{
if (!InBoundary(p, this.Boundary)) return;
if (points.Count < Capacity)
{
points.Add(p);
}
else
{
this.IsDivided = true;
if (this.upleft == null)
this.upleft = new QuadtreeNode(this.Boundary.Up, this.Boundary.Down + (this.Boundary.Up - this.Boundary.Down) / 2, this.Boundary.Left, this.Boundary.Left + (this.Boundary.Right - this.Boundary.Left) / 2);
if (this.upright == null)
this.upright = new QuadtreeNode(this.Boundary.Up, this.Boundary.Down + (this.Boundary.Up - this.Boundary.Down) / 2, this.Boundary.Left + (this.Boundary.Right - this.Boundary.Left) / 2, this.Boundary.Right);
if (this.leftbottom == null)
this.leftbottom = new QuadtreeNode(this.Boundary.Down + (this.Boundary.Up - this.Boundary.Down) / 2, this.Boundary.Down, this.Boundary.Left, this.Boundary.Left + (this.Boundary.Right - this.Boundary.Left) / 2);
if (this.rightbottom == null)
this.rightbottom = new QuadtreeNode(this.Boundary.Down + (this.Boundary.Up - this.Boundary.Down) / 2, this.Boundary.Down, this.Boundary.Left + (this.Boundary.Right - this.Boundary.Left) / 2, this.Boundary.Right);
this.upleft.Insert(p);
this.upright.Insert(p);
this.leftbottom.Insert(p);
this.rightbottom.Insert(p);
}
}
public List<Point> Query(Range range)
{
List<Point> qPoints = new List<Point>();
if (range._Point.Y + range.R <= this.Boundary.Down || range._Point.Y - range.R > this.Boundary.Up || range._Point.X - range.R >= this.Boundary.Right || range._Point.X + range.R < this.Boundary.Left)
return qPoints;
foreach (Point p in this.points)
if (InBoundary(p, range))
qPoints.Add(p);
if (this.IsDivided)
{
qPoints.AddRange(this.upleft.Query(range));
qPoints.AddRange(this.upright.Query(range));
qPoints.AddRange(this.leftbottom.Query(range));
qPoints.AddRange(this.rightbottom.Query(range));
}
return qPoints;
}
}
static void Main(string[] args)
{
string[] lineArray = Console.ReadLine().Split(' ');
int N = int.Parse(lineArray[0]), M = int.Parse(lineArray[1]);
QuadtreeNode root = new QuadtreeNode(30001, -1, -1, 30001);
for (int i = 0; i < N; ++i)
{
lineArray = Console.ReadLine().Split(' ');
root.Insert(new Point() { X = int.Parse(lineArray[0]), Y = int.Parse(lineArray[1]) });
}
for (int i = 0; i < M; ++i)
{
lineArray = Console.ReadLine().Split(' ');
List<Point> points = root.Query(new Range(int.Parse(lineArray[0]), int.Parse(lineArray[1]), int.Parse(lineArray[2])));
Console.WriteLine(points.Count);
}
Console.Write("");
}
}
}
Hiho 124 四叉树
最新推荐文章于 2018-07-21 18:19:28 发布