注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

fudq's AC Road

何以解忧,唯有AC!

 
 
 

日志

 
 

hdu 4145  

2012-03-11 08:30:40|  分类: ACM-hdu |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

http://acm.hdu.edu.cn/showproblem.php?pid=4145

给你2个大炮和一些敌人,每个大炮的攻击半径为r,A大炮和B大炮的攻击范围分别为r1和r2。问怎样才能使r1*r1 + r2*r2最小

解题思路:

将所有敌人距离A的距离从大到小排序,然后枚举A的半径,则B的半径就是A无法覆盖的点中距离B最远的距离。然后用一个变量来修改最小值。还要注意只用a和b的情况!

刚开始想错了:枚举每个敌人,比较它到2个大炮的距离,如果距离A近,则把这个距离与上个距离A近的敌人的距离比较,取较大者。反之同理处理B。这样就得到A和B炮的半径,进而得到答案。后来看了别人的报告,发现这样是有问题的。比如AB距离为100,他们中点旁边各有1个敌人,根据这种思路得到的距离为49*49 + 49 * 49 = 4802,而如果只用A,则只需要51 * 51 = 2601.

//hdu 4145
#include<iostream>
#include<string.h>
#include<queue>
#include<string>
#include<algorithm>
#include<math.h>
#include<stdio.h>
using namespace std;
#define N 100005
struct Point
{
 int x,y,dis1,dis2;
};

Point p1,p2,p3,f[N];
int Dis(Point a,Point b)
{
 return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}

bool cmp(Point a,Point b)
{
 return a.dis1>b.dis1;
}


int main()
{
#ifndef ONLINE_JUDGE
    freopen("testin.txt","r",stdin);
#endif
 int T,n,i,sum,minnum,d;
 scanf("%d",&T);
 while(T--)
 {
  scanf("%d%d%d%d",&p1.x,&p1.y,&p2.x,&p2.y);
  scanf("%d",&n);
  for(i=0;i<n;i++)
  {
   scanf("%d %d",&f[i].x,&f[i].y);
   f[i].dis1=Dis(p1,f[i]);
   f[i].dis2=Dis(p2,f[i]);
  }
  sort(f,f+n,cmp);
  minnum=f[0].dis1;
  for(i=1,d=0;i<n;i++)
  {
   if(f[i-1].dis2>d)
    d=f[i-1].dis2;
   sum=d+f[i].dis1;
   if(sum<minnum)
    minnum=sum;
  }
  if(f[n-1].dis2>d)
   d=f[n-1].dis2;
  if(d<minnum)
   minnum=d;
  printf("%d\n",minnum);
 }
    return 0;
}

  评论这张
 
阅读(126)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018