CF-contest385D

来源:互联网 发布:明河投资 知乎 编辑:程序博客网 时间:2024/05/16 19:35

CF_contest385D Bear and Floodlight

http://codeforces.com/contest/385/problem/D

题意:

  在一个二维平面内,初始有一只熊想要在晚上从(L, 0)走到(R,0)。你要沿着长度为(R - L)的线段行走。熊Y只在有光的地方行走。  有n个路灯,分布在平面上,照射方向可以任意旋转,照射距离无穷。  现在给出L,R和路灯坐标(Xi,  Yi),以及路灯能够照射的角度Ai。路灯摆放好之后就不能再转动,问这只熊最远能够走多少距离。

数据:

保证不会有相同的灯在同一坐标。(1 <= n <= 20, -1e5 <= L <= R <= 1e5).(-1000 <= xi <= 1000, 1 <= yi <= 1000, 1 <= ai <= 90).

思路:

 1. 状压dp,记dp[S]为使用了集合S内的灯之后向右能走到的最大x坐标。 2. 转移枚举不在集合内的一盏灯i,将其旋转到打在x轴上的线段左端点恰好为dp[S]。 3. 通过解三角形来计算增加的横坐标, 更新dp[S∪{i}].(可能为无穷远) 4. 注意:atan(double) 与 atan2 (double ,double) 之间的精度问题。 【atan2 返回的是方位角,即与 x 轴的夹角,取值范围为(-Pi,Pi] .】

  atan2 比 atan 稳定。  如:atan(y/x),当 y 远远大于 x 时,计算结果是不稳定的。  atan2(y,x)的做法:当 x 的绝对值比 y 的绝对值大时使用 atan(y/x);反之使用 atan(x/y)。这样就保证了数值稳定性。

代码:

#include <iostream>#include <string.h>#include <cstdio>#include <algorithm>#include <math.h>#include <vector>#include <queue>#include <map>using namespace std;typedef long long LL;typedef pair<int,int> P;const int N = 21;const int M = 100000;const double INF = 1e9;const double Pi = acos(-1);const double eps = 1e-9;int n,m,a,b,c;double l,r;double dp[1<<N];struct pt{    double x,y;    double a;}s[N];double ct(double x,double y,double a,double pos){    a=a*Pi/180;    double c=atan2(-y,-(x-pos));    if (a+c>-eps)        return INF;    return tan(a+Pi/2+c)*y+x;}int main(){    int cc,cas=1;    while (~scanf("%d%lf%lf",&n,&l,&r))    {        memset(dp,0,sizeof(dp));        dp[0]=l;        for (int i=0;i<n;i++)            scanf("%lf%lf%lf",&s[i].x,&s[i].y,&s[i].a);        for (int i=0;i<(1<<n);i++)            dp[i]=l;        for (int i=0;i<(1<<n);i++)        {            for (int j=0;j<n;j++)            {                if ((i&(1<<j))==0)                    dp[i|(1<<j)]=max(dp[i|(1<<j)],ct(s[j].x,s[j].y,s[j].a,dp[i]));            }        }        printf("%.9lf\n",min(dp[(1<<n)-1],r)-l);    }    return 0;}/*5 -10000 2621906 402 3334 64 7-161 565 4946 548 27122 466 285 -10000 100000993 94 2-503 76 2986 4 2-312 21 1338 6 22 3 53 1 455 1 451 0 11 1 301 0 11 1 451 0 20 2 90*/

东方

0 0
原创粉丝点击