HDU 4643 GSM
来源:互联网 发布:phpstorm格式化js代码 编辑:程序博客网 时间:2024/05/29 13:17
题意: 求一条线段上的点到其他m个点有多少个最短距离, m个点中没有两点到线段上的端点距离相等~
分析:用一个点和其他点的中垂线所在的半平面划分该点所在的区域, 该区域内任意一个点的距离到该点相对其他点距离最近.
具体实现:用一个足够大的矩形覆盖所有点, 然后划分区域, 最后判断所问线段和多少个区域(凸包)有交点~
分析:用一个点和其他点的中垂线所在的半平面划分该点所在的区域, 该区域内任意一个点的距离到该点相对其他点距离最近.
具体实现:用一个足够大的矩形覆盖所有点, 然后划分区域, 最后判断所问线段和多少个区域(凸包)有交点~
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <string>#include <cstring>#include <vector>#define FOR(i, n) for(int i = 0; i < n; i++)#define MEM(array) memset(array, 0, sizeof(array))#define eps 1e-7#define INF (int)1e5#define PI acos(-1.0)#define MAX 111using namespace std;inline int sgn(const double &x){return x > eps ? 1 : (x < -eps ? -1 : 0);}inline double sqr(const double &x){return x * x;}struct Point { double x, y; Point() {} Point(const double &xx, const double &yy):x(xx), y(yy) {} friend Point operator + (const Point &b, const Point &a) { return Point(b.x + a.x, b.y + a.y); } friend Point operator - (const Point &b, const Point &a) { return Point(b.x - a.x, b.y - a.y); } Point operator * (const double &a)const{ return Point(x * a, y * a); } Point operator / (const double &a) const{ return Point(x / a, y / a); } friend double dot(const Point &a, const Point &b) { return a.x *b.x + a.y * b.y; } friend double det(const Point &a, const Point &b) { return a.x * b.y - a.y * b.x; } double len( )const { return sqrt(dot(*this, *this)); } bool operator < (const Point &a)const { return sgn(x - a.x) < 0 || (sgn(x - a.x) == 0 && sgn(y - a.y) > 0); } bool operator == (const Point &a)const { return sgn(x - a.x ) == 0 && sgn(y - a.y) == 0; } Point rotate(const double &angle)const{ double x1 = x * cos(angle) - y * sin(angle); double y1 = x * sin(angle) + y * cos(angle); return Point(x1, y1); } void in() { scanf("%lf %lf", &x, &y); } void out()const { printf("%.4f %.4f\n", x, y); }}c[MAX], b[MAX];int n, m;struct Line{ Point s, t; Line(){} Line(const Point &ss, const Point &tt):s(ss), t(tt){} //获取s t的中垂线的s所在的半平面线(左边) friend void getPlaneLine(const Line &line, Line &res){ Point mid = (line.s + line.t)/ 2; Point fa = line.dir().rotate(PI / 2); res = Line(mid, mid + fa); } //线段和直线 friend bool lineInsectLinevEx(const Line &l1, const Line &lv, Point &res){ int res1 = sgn( det(l1.s - lv.s, lv.t - lv.s) ); int res2 = sgn( det(l1.t - lv.s, lv.t - lv.s) ); if(res1 * res2 < 0){ double s1 = det(l1.s - lv.s, lv.dir()), s2 = det(l1.t - lv.s, lv.dir()); res = (l1.t * s1 - l1.s * s2 ) /(s1 - s2); return 1; } return 0; } //线段和线段, 不包含端点 friend bool lineInsectLineEx(const Line &l1, const Line &l2){ int res1 = sgn( det(l1.s - l2.s, l2.t - l2.s) * det( l1.t - l2.s, l2.t - l2.s) ) ; int res2 = sgn( det(l2.s - l1.s, l1.t - l1.s) * det( l2.t - l1.s, l1.t - l1.s) ) ; return res1 < 0 && res2 < 0; } Point dir()const{ return t - s; } void out()const{ s.out(); t.out(); }};struct Poly{ vector<Point> p; friend Poly getCut(const Poly &poly, const Line &line){ int tn = poly.p.size(); Poly resp; for(int i = 0; i < tn; i++){ Point va = poly.p[i] - line.s, vb = line.dir(); int res = sgn(det(va, vb)); if(res <= 0){//in half resp.p.push_back(poly.p[i]); }else { int j = i - 1, k = i + 1; if(j < 0)j = tn - 1; if(k > tn - 1)k = 0; int id[] = {j, k}; FOR(kk, 2){ va = poly.p[id[kk]] - line.s; res = sgn(det(va, vb) ); Point ins; Line l1(poly.p[i], poly.p[id[kk]]); if(res < 0 && lineInsectLinevEx( l1, line, ins)){ resp.p.push_back(ins); } } } } return resp; } //和线段的是否有交,不包含端点 bool isInsectLineEx(const Line &l1){ if(isContain(l1.s) == true || isContain(l1.t) == true)return true; int tn = p.size(); for(int i = 0; i < tn; i++){ Line lv(p[i], p[(i + 1)%tn]); if(lineInsectLineEx(lv, l1))return true; } return false; } bool isContain(const Point &t){ int sign = 0; int tn = p.size(); for(int i = 0; i < tn; i++){ int signt = sgn( det( p[i] - t, p[(i + 1)%tn] - t) ); if(signt){ if(sign){ if(sign != signt )return 0; }else { sign = signt; } }else return 0; } return 1; }}poly[MAX], rect;void init(){ FOR(i, n){ c[i].in(); } FOR(j, m){ b[j].in(); }}void getPoly(){ FOR(i, m){ Poly cur = rect; FOR(j, m){ if(j == i)continue; Line line(b[i], b[j]), res; getPlaneLine(line, res);// res.out(); cur = getCut(cur, res); } poly[i] = cur; }}bool v[MAX];int judge(int a, int b){ int ans = 0; memset(v, 0, sizeof(v));// for(int i = a; i < b; i++)太二不能多说 { for(int j = 0; j < m; j++){ if(poly[j].isInsectLineEx(Line(c[a], c[b]))){ v[j] = 1; } } } for(int i = 0; i < m; i++){ if(v[i])ans ++, v[i] = 0; } return ans - 1;}void solve(){ int k ,a, b; cin>>k; while(k--){ cin>>a>>b; cout<<judge(a - 1, b - 1)<<endl; }}int main(){ rect.p.push_back(Point(-INF, -INF)); rect.p.push_back(Point(INF, -INF)); rect.p.push_back(Point(INF, INF)); rect.p.push_back(Point(-INF, INF)); while(cin>>n>>m){ init(); getPoly(); solve(); } return 0;}/**/
- HDU 4643 GSM
- hdu 4643GSM
- HDU-4643-GSM(DFS)
- HDU 4643 GSM
- hdu 4643 GSM(几何)
- HDU 4643 GSM(计算几何)
- hdu 4643 GSM 计算几何 - 点线关系
- HDU 4643 GSM 简单计算几何 (2013多校联合)
- HDU 4643 GSM(计算几何求线段的中垂线)
- GSM
- GSM
- GSM
- GSM
- GSM
- GSM
- GSM
- GSM
- GSM
- python中计时工具timeit模块的基本用法
- 优酷去广告代码
- java注解应用实例 - Annotation, 自定义注解, 注解类规则
- Redis:安装、配置、操作和简单代码实例(C语言Client端)
- 可空类型
- HDU 4643 GSM
- 解决VS2010中菜单设置快捷键 运行后不显示的问题
- Windows7 32位机上,OpenCV中配置GPU操作步骤
- Ant从CVS checkout项目
- 读写锁
- 图像通道
- Amazon S3 功能介绍
- SEO不能忽视的链接效率
- css图片垂直居中