zoukankan      html  css  js  c++  java
  • llg的农场(farm)

      评测传送门

    【题目描述】

    llg 是一名快乐的农民,他拥有一个很大的农场,并且种了各种各样的瓜果蔬菜,到了每年秋天,他就可以把所有蔬菜水果卖到市场上,这样他就可以获利。但今年他遇到了一个难题——有许多鸟来到了他的农场偷吃他的瓜果蔬菜。不知所措的 llg 只好求助于 jump,万能的 jump 于是给了 llg 一些稻草人(据说可以驱鸟)。每个庄稼都可以看做是坐标系里面的一个点,当它处于某个稻草人的范围内时就可以视为被保护。可是每个稻草人的辐射范围有限,根据测定,每个稻草人的辐射范围都是一个半径为 R 的圆,llg 很懒,所以他只打算把稻草人放在坐标系的 x 轴上,而任何庄稼(x,y)都满足 y>0。图中的小红点就是庄稼,蓝点即稻草人放的位置。现在请你来帮助 llg设计一个方案,用尽可能少的稻草人来保证所有庄稼都是安全的。若存在无法覆盖的庄稼或者 jump 给的稻草人不够覆盖所有庄稼,请输出-1。

     


    【输入数据】
    每个测试点含多组数据
    每组数据第一行包含 n,R,C;分别表示庄稼的数量、稻草人的最大覆盖半径,命题人:黎锦灏
    稻草人的数量。
    接下来 n 行,每行包括两个数 xi,yi 表示一个点的坐标
    输入以“0 0 0”结尾


    【输出数据】
    对于每组数据,请输出最小要用多少稻草人,才能保证覆盖所有庄稼。若无法覆
    盖或数量不够,请输出-1。

    【数据约定】
    对于 30%的数据,1<=n<=3000
    对于 100%的数据, 1<=n<=50000,1<=数据组数<=10,其余数据均保证不会超过 int的范围

    思路:

      对于任意一个庄稼 我们可以很轻松的得出能覆盖到此庄稼的的稻草人位置 即圆心位置

      令庄稼位置为(x,y)

      则稻草人的横坐标范围为[x-sqrt(r*r-y*y),x+sqrt(r*r-y*y)] 边界就是庄稼恰好在圆心上

      我们求出每个庄稼所对应的圆心范围后 题目就转化成了:

      有若干可能互相重合的线段 求最少的点数使每条线段上至少有一点

      然后按横坐标排序

      贪心 对于排序之后的线段 取最右端为最优(尽可能覆盖到多的点)

      具体见代码吧

    CODE:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #define go(i,a,b) for(register int i=a;i<=b;i++)
     6 #define db double
     7 #define M 50000+10
     8 using namespace std;
     9 int read()
    10 {
    11     int x=0,y=1;char c=getchar();
    12     while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();}
    13     while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    14     return x*y;
    15 }
    16 int n,r,m,x,y,ans;
    17 bool fg;
    18 struct node {db l,r;}a[M];
    19 bool cmp(node u,node v){if(u.l!=v.l) return u.l<v.l;return u.r<v.r;}
    20 int main()
    21 {
    22     freopen("1.in","r",stdin);
    23     freopen("1.out","w",stdout);
    24     while(1)
    25     {
    26         n=read();r=read();m=read();ans=1;fg=0;
    27         if(!n&&!r&&!m) return 0;
    28         go(i,1,n)
    29         {
    30             x=read();y=read();
    31             if(y>r||fg) {fg=1;continue ;}
    32             db k=(db)sqrt(r*r-y*y);
    33             a[i].l=(db)x-k;
    34             a[i].r=(db)x+k;
    35         }
    36         if(fg) {puts("-1");continue ;}
    37         sort(a+1,a+n+1,cmp);
    38         db nw=a[1].r;
    39         go(i,2,n)
    40         {
    41             if(a[i].l>nw) {ans++;nw=a[i].r;}
    42             else nw=min(nw,a[i].r);
    43         }
    44         if(ans>m) {puts("-1");continue ;}
    45         printf("%d
    ",ans);
    46     }
    47     return 0;
    48 }
    View Code
    光伴随的阴影
  • 相关阅读:
    CSS浮动(float、clear)通俗讲解
    JAVA 类的加载
    数据库操作 delete和truncate的区别
    正则表达式 匹配相同数字
    Oracle EBS OM 取消订单
    Oracle EBS OM 取消订单行
    Oracle EBS OM 已存在的OM订单增加物料
    Oracle EBS OM 创建订单
    Oracle EBS INV 创建物料搬运单头
    Oracle EBS INV 创建物料搬运单
  • 原文地址:https://www.cnblogs.com/forward777/p/10338294.html
Copyright © 2011-2022 走看看