题意:给一些传感器,范围在r内,再给一些询问点,问这些点能有几个传感器收到,当有墙隔绝时信号减弱,范围变小
分析:set存储传感器,用set的find来查找是否是传感器。因为询问点少,可以枚举询问点的r的范围的所有整数点,+线段相交新模板:)
#include <bits/stdc++.h> using namespace std; typedef long long ll; struct Point { int x, y; Point() {} Point(int x, int y) : x (x), y (y) {} Point operator - (const Point &r) const { return Point (x - r.x, y - r.y); } bool operator < (const Point &r) const { return x < r.x || (x == r.x && y < r.y); } int operator ^ (const Point &r) const { //叉积 return x * r.y - y * r.x; } bool operator == (const Point &r) const { return (x == r.x && y == r.y); } }; typedef Point Vector; Point read_point(void) { int x, y; scanf ("%d%d", &x, &y); return Point (x, y); } int dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; } int cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; } bool on_seg(Point p, Point a, Point b) { return (cross (a - p, b - p) == 0 && dot (a - p, b - p) < 0); } //2 规范相交 1 非规范相交 0 不相交 //有误 int can_seg_seg_inter(Point a1, Point a2, Point b1, Point b2) { int c1 = cross (a2 - a1, b1 - a1), c2 = cross (a2 - a1, b2 - a1), c3 = cross (b2 - b1, a1 - b1), c4 = cross (b2 - b1, a2 - b1); if ((c1 ^ c2) == -2 && (c3 ^ c4) == -2) return 2; return (on_seg (a1, b1, b2) || on_seg (a2, b1, b2) || on_seg (b1, a1, a2) || on_seg (b2, a1, a2)); } bool check(Point a1, Point a2, Point b1, Point b2) { if (min (a1.x, a2.x) > max (b1.x, b2.x) || min (a1.y, a2.y) > max (b1.y, b2.y) || min (b1.x, b2.x) > max (a1.x, a2.x) || min (b1.y, b2.y) > max (a1.y, a2.y)) return false; int c1 = (a1 - a2) ^ (a1 - b1); int c2 = (a1 - a2) ^ (a1 - b2); int c3 = (b1 - b2) ^ (b1 - a1); int c4 = (b1 - b2) ^ (b1 - a2); return 1ll * c1 * c2 <= 0 && 1ll * c3 * c4 <= 0; } int s, r, w, p; Point p1[15], p2[15]; set<Point> S; int squ(int x) { return x * x; } int get_dis2(Point a, Point b) { return squ (a.x - b.x) + squ (a.y - b.y); } bool find_senor(Point a, Point b) { if (S.find (b) != S.end ()) { int d2 = get_dis2 (a, b); if (d2 > squ (r)) return false; int cnt = 0; for (int i=1; i<=w; ++i) { //if (can_seg_seg_inter (a, b, p1[i], p2[i])) cnt++; if (check (a, b, p1[i], p2[i])) cnt++; } if (cnt > r) return false; return d2 <= squ (r - cnt); } else return false; } void run(Point a, vector<Point> &vec) { for (int i=-r; i<=r; ++i) { int d = sqrt (squ (r) - squ (i)); for (int j=-r; j<=r; ++j) { Point b = Point (a.x + i, a.y + j); if (find_senor (a, b)) vec.push_back (b); } } } int main(void) { int T; scanf ("%d", &T); while (T--) { scanf ("%d%d%d%d", &s, &r, &w, &p); S.clear (); for (int i=1; i<=s; ++i) { S.insert (read_point ()); } for (int i=1; i<=w; ++i) { p1[i] = read_point (); p2[i] = read_point (); } vector<Point> vec; for (int i=1; i<=p; ++i) { Point a = read_point (); vec.clear (); run (a, vec); sort (vec.begin (), vec.end ()); printf ("%d", vec.size ()); for (int i=0; i<vec.size (); ++i) { printf (" (%d,%d)", vec[i].x, vec[i].y); } puts (""); } } return 0; }