zoukankan      html  css  js  c++  java
  • poj 1106 Transmitters (计算几何,叉积||极角排序)

    Transmitters
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 4817   Accepted: 2576

    Description

    In a wireless network with multiple transmitters sending on the same frequencies, it is often a requirement that signals don't overlap, or at least that they don't conflict. One way of accomplishing this is to restrict a transmitter's coverage area. This problem uses a shielded transmitter that only broadcasts in a semicircle. 

    A transmitter T is located somewhere on a 1,000 square meter grid. It broadcasts in a semicircular area of radius r. The transmitter may be rotated any amount, but not moved. Given N points anywhere on the grid, compute the maximum number of points that can be simultaneously reached by the transmitter's signal. Figure 1 shows the same data points with two different transmitter rotations. 

    All input coordinates are integers (0-1000). The radius is a positive real number greater than 0. Points on the boundary of a semicircle are considered within that semicircle. There are 1-150 unique points to examine per transmitter. No points are at the same location as the transmitter. 

    Input

    Input consists of information for one or more independent transmitter problems. Each problem begins with one line containing the (x,y) coordinates of the transmitter followed by the broadcast radius, r. The next line contains the number of points N on the grid, followed by N sets of (x,y) coordinates, one set per line. The end of the input is signalled by a line with a negative radius; the (x,y) values will be present but indeterminate. Figures 1 and 2 represent the data in the first two example data sets below, though they are on different scales. Figures 1a and 2 show transmitter rotations that result in maximal coverage.

    Output

    For each transmitter, the output contains a single line with the maximum number of points that can be contained in some semicircle.

    Sample Input

    25 25 3.5
    7
    25 28
    23 27
    27 27
    24 23
    26 23
    24 29
    26 29
    350 200 2.0
    5
    350 202
    350 199
    350 198
    348 200
    352 200
    995 995 10.0
    4
    1000 1000
    999 998
    990 992
    1000 999
    100 100 -2.5

    Sample Output

    3
    4
    4

    Source

     
    题意是说,给定一个固定圆心和半径的半圆,问半圆旋转到哪个角度覆盖的点最多。
    当点在边界上认为也是在半圆里面。
    分析可知,当半圆恰好旋转道某角度使得点在边界上的时候一定不会比对应的最优的情况更坏。
    所以我们可以首先剔除掉那些距离圆心距离大于r的点。
    然后枚举剩下的每个点,以当前点连接圆心,作为当前圆的半径(这样得到的是两个圆,左边一个右边一个,但我们只考虑一个就好)
    看有多少点在当前半圆的同一侧,记录为sum
    然后更新所有点得到的sum的最大值即可。
     
    不需要极角排序。。。直接枚举就行。。
    判断在一侧的方法是,用叉积。 小于0逆时针大于0顺时针。。。嗯。都可以。。。
      1 /*************************************************************************
      2     > File Name: code/poj/1106.cpp
      3     > Author: 111qqz
      4     > Email: rkz2013@126.com 
      5     > Created Time: 2015年11月09日 星期一 09时28分51秒
      6  ************************************************************************/
      7 
      8 #include<iostream>
      9 #include<iomanip>
     10 #include<cstdio>
     11 #include<algorithm>
     12 #include<cmath>
     13 #include<cstring>
     14 #include<string>
     15 #include<map>
     16 #include<set>
     17 #include<queue>
     18 #include<vector>
     19 #include<stack>
     20 #include<cctype>
     21 #define fst first              
     22 #define sec second      
     23 #define lson l,m,rt<<1
     24 #define rson m+1,r,rt<<1|1
     25 #define ms(a,x) memset(a,x,sizeof(a))
     26 using namespace std;
     27 const double eps = 1E-8;
     28 const int dx4[4]={1,0,0,-1};
     29 const int dy4[4]={0,-1,1,0};
     30 typedef long long LL;
     31 const int inf = 0x3f3f3f3f;
     32 const  int N=2E4+7;
     33 
     34 int n;
     35 double r;
     36 int dblcmp( double d)
     37 {
     38     return d<-eps?-1:d>eps;
     39 }
     40 struct point
     41 {
     42     double x,y;
     43     point(){}
     44     point(double _x,double _y):
     45     x(_x),y(_y){};
     46 
     47     void input()
     48     {
     49     scanf("%lf %lf",&x,&y);
     50     }
     51     
     52 
     53     point operator - (const point &p)const{
     54     return point(x-p.x,y-p.y);
     55     }
     56     double operator ^(const point &p)const{
     57     return x*p.y-y*p.x;
     58     }
     59     double dis(point p)
     60     {
     61     return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
     62     }
     63 }tmp[N],c,p[N];
     64 int main()
     65 {
     66   #ifndef  ONLINE_JUDGE 
     67    freopen("in.txt","r",stdin);
     68   #endif
     69     while (~scanf("%lf %lf %lf",&c.x,&c.y,&r))
     70     {
     71     int cnt = 0 ;
     72     if (dblcmp(r)<=0) break;
     73     scanf("%d",&n);
     74     for ( int i = 0 ;i  < n ; i ++)
     75     {
     76         tmp[i].input();
     77         double d =c.dis(tmp[i]);
     78         if (dblcmp(d-r)<=0)
     79         {
     80         //p[cnt]=tmp[i];
     81         p[cnt].x=tmp[i].x;
     82         p[cnt].y=tmp[i].y;
     83         cnt++;
     84         }
     85     }
     86     int ans = 0;
     87     for ( int i = 0 ; i < cnt ; i++)
     88     {
     89         int sum = 1 ;
     90         for ( int j = 0 ; j < cnt ; j++)
     91         {
     92         double cross = (c-p[i])^(c-p[j]);
     93         if (cross>=0&&i!=j)
     94         {
     95             sum++;
     96         }
     97         }
     98         ans = max(sum,ans);
     99     }
    100     printf("%d
    ",ans);
    101     }
    102   
    103    
    104  #ifndef ONLINE_JUDGE  
    105   #endif
    106   fclose(stdin);
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    年薪 80w 的程序员被鄙视了!工资再高,你也替代不了父母眼中的医师公!
    C语言中,能和指针并排核心知识的结构体,该如何掌握?
    编程的终点在何方?我似乎理解了编程的意义!为了在世上留下自己的痕迹!
    作为一个优秀的程序员,真的需要精通C语言吗?精通又需要多久的沉淀?
    用C语言验证 “6174黑洞之谜”!万物始于C,编程世界的黑洞!
    打印未决信号集
    信号捕捉
    alarm函数
    输入输出运算符重载
    自增自减运算符重载
  • 原文地址:https://www.cnblogs.com/111qqz/p/4949128.html
Copyright © 2011-2022 走看看