http://acm.hdu.edu.cn/showproblem.php?pid=4216
题意:给你一个坐标(炸弹爆炸的位置),原本你在坐标原点,给你一些向量,然后沿着这些向量走(可以往反向), 问你最远能力爆炸点有多远.
枚举角度,从0度到360度,每次增加0.1度,把每个向量用点乘的性质尽量向所枚举的方向上靠拢(因为可以反向)。最后输出这么多角度中离爆炸点最远的位置。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 105
#define M 1000000
int xo,yo;
struct vector
{
int x,y;
}v[N];
int jia(double i1,int j)
{
double x,y;
if (i1<=180) y=100;
else y=-100;
x=y/tan(i1);//这个生成所枚举角度对应的向量的方法很好
return x*v[j].x+y*v[j].y;
}
long long dis(int x,int y)
{
return (x-xo)*(x-xo)+(y-yo)*(y-yo);
}
int main()
{
//freopen("a","r",stdin);
int t;
long long ans;
scanf("%d",&t);
int n,i,kk,x,y,j;
for (kk=1;kk<=t;kk++)
{
scanf("%d%d%d",&n,&xo,&yo);
printf("Case %d: ",kk);
ans=-1;
for (i=1;i<=n;i++) scanf("%d%d",&v[i].x,&v[i].y);
for (double i1=0;i1<360;i1+=0.1)
{
x=0;
y=0;
for (j=1;j<=n;j++)
if (jia(i1,j)>=0)
{
x+=v[j].x;
y+=v[j].y;
}
else
{
x-=v[j].x;
y-=v[j].y;
}
long long s=dis(x,y);
if (s>ans) ans=s;
}
double ans1=ans;
ans1=sqrt(ans1);
printf("%.3lf\n",ans1);
}
return 0;
}