Hiho 124 四叉树

来源:互联网 发布:vb 按键精灵 编辑:程序博客网 时间:2024/06/07 00:12
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("");        }    }}
0 0