zoukankan      html  css  js  c++  java
  • 守护雅典娜 HDU-4562

    vj链接:

    守护雅典娜

     
    题目描述:
    许多塔防游戏都是以经典的“守护雅典娜”为原型的。玩家需要建立各种防御工具来阻止怪物接近我们的女神——雅典娜。 

    这里,我们可以建造的防御工具只有标准圆形状的防御墙,建立在雅典娜与怪物出生点之间的防御墙数目越多,胜利的希望就越大。这里,将问题简化到一个二维坐标系里,并且假设雅典娜的坐标为原点(0, 0),怪物出生点的坐标为(X, Y)。有N个给定圆心坐标与半径的防御墙可以供玩家选择建立,但要保证所有的圆都不发生相切或相交的情况。注意这些雅典娜位置与怪物出生点位置也不能在墙壁的边缘,即表示防御墙的圆上。点的面积与墙的厚度都很小,可以忽略不计。

    记住,在游戏开始之后,怪物可以沿着任何轨迹,选择突破最少的圆形防御墙来到雅典娜的身边,而一个防御墙一旦被突破,它就会失去保护作用。所以,你的方案必须足够优秀。为了守护女神,快去找出最优的建设方案吧!

    Input输入第一行为T,表示有T组测试数据。 
    每组数据以三个整数N,X,Y开始,接下去的N行每行包括三个整数Xi,Yi,Ri,表示一个可以选择的圆心为(Xi, Yi)半径为Ri的防御墙。 


    1. 1 <= T <= 100 
    2. 1 <= N <= 1000 
    3. 1 <= Ri <= 10 000 
    4. -10 000 <= X, Y, Xi, Yi <= 10 000,坐标不会相同Output对每组数据,先输出为第几组数据,然后输出能够间隔在雅典娜与怪物出生点之间最多的防御墙数目。Sample Input

    3
    1 5 5
    1 0 2
    1 5 5
    1 0 9
    3 5 5
    1 0 2
    4 5 2
    2 0 6

    Sample Output

    Case 1: 1
    Case 2: 0
    Case 3: 2
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 using namespace std;
      7 int T,N,X,Y;
      8 int xx,yy,rr,k;
      9 struct node{
     10     int x;
     11     int y;
     12     int r;
     13     int num;
     14 }ya[1100],guai[1100];
     15 int dp1[1100];
     16 int dp2[1100];
     17 int dp3[1100];
     18 int cmp(node a,node b)
     19 {
     20     return a.r<b.r;
     21 }
     22 int judge(node a,node b)
     23 {
     24     int d=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
     25     if((a.r-b.r)*(a.r-b.r)<=d&&d<=(a.r+b.r)*(a.r+b.r))
     26     return 0;//两圆不是相离的也不是内含的就返回0
     27     else
     28     return 1; 
     29 }
     30 int main()
     31 {
     32     cin>>T;
     33     while(T--)
     34     {
     35         int l1=0,l2=0;
     36         memset(dp1,0,sizeof(dp1));
     37         memset(dp2,0,sizeof(dp2));
     38         memset(dp3,0,sizeof(dp3));
     39         cin>>N>>X>>Y;
     40         for(int i=1;i<=N;i++)
     41         {
     42             cin>>xx>>yy>>rr;
     43             if((xx*xx+yy*yy<rr*rr)&&(X-xx)*(X-xx)+(Y-yy)*(Y-yy)>rr*rr)
     44             {
     45             //将包含怪兽的或是不包含雅典娜的排除掉 
     46                 ya[l1].x=xx;
     47                 ya[l1].y=yy;
     48                 ya[l1].r=rr;
     49                 ya[l1].num=1;
     50                 l1++;
     51             }
     52             if((xx*xx+yy*yy>rr*rr)&&(X-xx)*(X-xx)+(Y-yy)*(Y-yy)<rr*rr)
     53             {//将包含雅典娜的或是不包含怪兽的排除掉 
     54                 guai[l2].x=xx;
     55                 guai[l2].y=yy;
     56                 guai[l2].r=rr;
     57                 guai[l2].num=1;
     58                 l2++;
     59             }
     60         }
     61         sort(ya,ya+l1,cmp);
     62         //以半径从小到大排序,使得相邻的两个圆便于比较 
     63         sort(guai,guai+l2,cmp);
     64         int ans=0;
     65         if(l1==1)
     66         {
     67             ans=max(ans,ya[0].num);
     68         } 
     69         //对雅典娜进行动态规划 
     70         for(int i=1;i<l1;i++)
     71         {
     72             for(int j=0;j<i;j++)
     73             {
     74                 if(judge(ya[i],ya[j]))//判断两个圆是否是内含的 
     75                 {
     76                  ya[i].num=max(ya[i].num,ya[j].num+1);
     77                 }
     78                 ans=max(ans,ya[i].num);
     79                 
     80             }     
     81         }
     82         //对怪兽进行动态规划 
     83         if(l2==1)
     84         {
     85             ans=max(ans,guai[0].num);
     86         }
     87         for(int i=1;i<l2;i++)
     88         {
     89             for(int j=0;j<i;j++)
     90             {
     91                 if(judge(guai[i],guai[j]))
     92                 {
     93                  guai[i].num=max(guai[i].num,guai[j].num+1);
     94                 }
     95                 ans=max(ans,guai[i].num);
     96             //ans代表的是只雅典娜或是只是怪兽的最大屏障数,总的只会比ans大于等于,不会小于 
     97             }
     98         }
     99         //将两者动态规划的结果合并 
    100         for(int i=0;i<l1;i++)
    101         {
    102             for(int j=0;j<l2;j++)
    103             {
    104                 if(judge(ya[i],guai[j]))
    105                 {
    106                     ans=max(ans,ya[i].num+guai[j].num);
    107                 }
    108             }
    109         }
    110         printf("Case %d: %d
    ",k++,ans); 
    111     }
    112 return 0;
    113 } 
     
  • 相关阅读:
    sql 存储过程参数为空则不作为条件
    sql 将某一列转成字符串并且去掉最后一个逗号
    日期时间格式加减操作
    未能加载文件或程序集“NPOI”或它的某一个依赖项
    SqlBulkCopy 批量插入
    字符串操作
    CSS基本知识汇总
    ORACLE创建表之前判断表是否存在与SQL Server 对比使用
    SELECT INTO FROM 与 INSERT INTO SELECT区别鉴赏
    SQL 养成一个好习惯是一笔财富
  • 原文地址:https://www.cnblogs.com/1013star/p/9300174.html
Copyright © 2011-2022 走看看