Codeforces Gym 101174 A Within Arm's Reach 贪心 手臂

#include<iostream>
#include<stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <math.h>
using namespace std;
#define LL long long
const int maxn=25;
double a[maxn],l[maxn],r[maxn];
double ex,ey;
#define  dis(x1,y1,x2,y2) hypot(x1-x2,y1-y2)
#define sqr(x) ((x)*(x))
#define eps 1e-8
void changend()
{
    if(ex==0&&ey==0){
        ex+=eps,ey+=eps;
        return ;
    }
    double ed=dis(0,0,ex,ey);
    double t=1;
    if(ed>r[0])t=r[0]/ed;
    if(ed<l[0])t=l[0]/ed;
    ex*=t;ey*=t;
}
int n;
bool check(double q,double w,double e)
{
    double a[]={q,w,e};
    sort(a,a+3);
    return a[0]+a[1]+eps>=a[2];
}
void dfs(double ,double ,int);
void work(double x,double y,double d,double len,double d3,int cur)
{
    double cosfi=(sqr(d)+sqr(len)-sqr(d3))/(d*len*2);
    if(cosfi>1)cosfi=1;
    if(cosfi<-1)cosfi=-1;

    double fi=acos(cosfi);
    double xx=ex-x,yy=ey-y;
    double nx=xx*cos(fi)-yy*sin(fi),ny=xx*sin(fi)+yy*cos(fi);

    dfs(x+nx/d*len,y+ny/d*len,cur+1);
}
void dfs(double x,double y,int cur) //i+1...n的手臂伸直作为一条边 a[cur]作为另一条边,当前点与终点连线作为第三条边
{
    if(cur!=0) printf("%f %f\n",x,y);
    if(cur==n)return ;
    double d=dis(x,y,ex,ey);
    if(check(d,l[cur+1],a[cur])){
        work(x,y,d,a[cur],l[cur+1],cur);
    }
    else
        work(x,y,d,a[cur],r[cur+1],cur);
}
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lf",a+i);
    scanf("%lf%lf",&ex,&ey);
    l[n]=r[n]=0;
    for(int i=n-1;i>=0;i--)
    {
        if(a[i]<l[i+1]) l[i]=l[i+1]-a[i];
        else if(a[i]>r[i+1])l[i]=a[i]-r[i+1];
        else l[i]=0;
        r[i]=r[i+1]+a[i];
    }
    changend();
    dfs(0,0,0);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/polya/p/9711040.html