[NOI2010]:成长快乐

传送门
目前30 at 12.14
话说洛谷此题样例错了,而且第二个点是第十个点。。。
首先第一个点可以手算,10分
第二个点爆搜:

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
using namespace std;
const int N=1e5+5;
const double eps=1e-12;
struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y):x(_x),y(_y){}
    inline Point operator + (const Point& b) const {return Point(x+b.x,y+b.y);}
    inline Point operator - (const Point& b) const {return Point(x-b.x,y-b.y);}
    inline Point operator * (double b) const {return Point(x*b,y*b);}
}nemo,P[N],v[N];
inline int dcmp(double x){
    if(fabs(x)<eps)return 0;
    return x>eps?1:-1;
}
inline double dis(const Point& a,const Point& b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
inline double dis2(const Point& a,const Point& b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
inline double Dot(const Point& a,const Point& b){return a.x*b.x+a.y*b.y;}
inline double Mod(const Point& a){return sqrt(Dot(a,a));}
inline double Mod2(const Point& a){return Dot(a,a);}
int n,s[N],use[N];
double w0,V,T,w[N];
double maxw;
int ans[N],anscnt;
double tm[N],anstm[N];
Point pos[N],anspos[N];
inline double solve(double a,double b,double c){
    double d=b*b-4.0*a*c;
    if(dcmp(d)<0)return -1;
    d+=eps;d=sqrt(d);
    double x1=(-b+d)/(2.0*a),x2=(-b-d)/(2.0*a);
    double x=max(x1,x2);
    if(x<0)return -1;
    if(x1<0)x1=1e9;
    if(x2<0)x2=1e9;
    x=min(x1,x2);
    return x;
}
inline void dfs(int cnt,double noww,double nowt,Point now){
    if(nowt>T)return;
    if(noww>maxw){
        for(int i=1;i<cnt;i++)ans[i]=s[i];
        for(int i=1;i<cnt;i++)anstm[i]=tm[i];
        for(int i=1;i<cnt;i++)anspos[i]=pos[i];
        maxw=noww;anscnt=cnt;
    }
    if(cnt>n)return;
    for(int i=1;i<=n;i++){
        if(use[i])continue;
        if(w[i]>=noww+eps)continue;
        Point B=P[i]+v[i]*nowt,A=now;
        double a=Mod2(v[i])-V*V;
        double b=-2.0*Dot(v[i],A-B);
        double c=dis2(A,B);
        double tmp=solve(a,b,c);
        if(tmp==-1)continue;
        use[i]=1;s[cnt]=i;tm[cnt]=tmp+nowt;pos[cnt]=B+v[i]*tmp;
        dfs(cnt+1,noww+w[i],nowt+tmp,pos[cnt]);
        use[i]=0;
    }
}
int main(){
    freopen("nemo2.in","r",stdin);
    freopen("nemo2.out","w",stdout);
    scanf("%lf %lf %lf %lf %lf",&w0,&V,&T,&nemo.x,&nemo.y);scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lf %lf %lf %lf %lf",&w[i],&P[i].x,&P[i].y,&v[i].x,&v[i].y);
    dfs(1,w0,0,nemo);
    printf("%d\n",anscnt-1);
    printf("%.6lf\n",maxw-w0);
    for(int i=1;i<anscnt;i++)printf("%.6lf %.6lf %.6lf %d\n",anstm[i],anspos[i].x,anspos[i].y,ans[i]);
    return 0;
}

第三个点因为每次只能吃一个,所以排序然后模拟即可:

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
using namespace std;
const int N=1e5+5;
const double eps=1e-12;
struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y):x(_x),y(_y){}
    inline Point operator + (const Point& b) const {return Point(x+b.x,y+b.y);}
    inline Point operator - (const Point& b) const {return Point(x-b.x,y-b.y);}
    inline Point operator * (double b) const {return Point(x*b,y*b);}
}nemo,P[N],v[N];
struct fish{
    Point pos,v;double w;int id;
}F[N];
inline bool cmp(const fish& a,const fish& b){return a.w<b.w;}
inline int dcmp(double x){
    if(fabs(x)<eps)return 0;
    return x>eps?1:-1;
}
inline double dis(const Point& a,const Point& b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
inline double dis2(const Point& a,const Point& b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
inline double Dot(const Point& a,const Point& b){return a.x*b.x+a.y*b.y;}
inline double Mod(const Point& a){return sqrt(Dot(a,a));}
inline double Mod2(const Point& a){return Dot(a,a);}
int n,s[N],use[N];
double w0,V,T,w[N];
double tm[N];
Point pos[N];
inline double solve(double a,double b,double c){
    double d=b*b-4.0*a*c;
    if(dcmp(d)<0)return -1;
    d+=eps;d=sqrt(d);
    double x1=(-b+d)/(2.0*a),x2=(-b-d)/(2.0*a);
    double x=max(x1,x2);
    if(x<0)return -1;
    if(x1<0)x1=1e9;
    if(x2<0)x2=1e9;
    x=min(x1,x2);
    return x;
}
int main(){
    freopen("nemo4.in","r",stdin);
    freopen("nemo4.out","w",stdout);
    scanf("%lf %lf %lf %lf %lf",&w0,&V,&T,&nemo.x,&nemo.y);scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lf %lf %lf %lf %lf",&F[i].w,&P[i].x,&P[i].y,&v[i].x,&v[i].y)
    ,F[i].pos=P[i],F[i].v=v[i],F[i].id=i;
    sort(F+1,F+n+1,cmp);
    int cnt=1;double noww=w0,nowt=0;Point now=nemo;
    for(int i=1;i<=n;i++){
        Point B=F[i].pos+F[i].v*nowt,A=now;
        double a=Mod2(F[i].v)-V*V;
        double b=-2.0*Dot(F[i].v,A-B);
        double c=dis2(A,B);
        double tmp=solve(a,b,c);
        s[cnt]=F[i].id;tm[cnt]=tmp+nowt;pos[cnt]=B+F[i].v*tmp;
        noww+=F[i].w;nowt+=tmp;now=pos[cnt];
        cnt++;
    }
    printf("%d\n",cnt-1);
    printf("%.6lf\n",noww-w0);
    for(int i=1;i<cnt;i++)printf("%.6lf %.6lf %.6lf %d %.6lf\n",tm[i],pos[i].x,pos[i].y,s[i],F[i].w);
    return 0;
}
发布了279 篇原创文章 · 获赞 49 · 访问量 7万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览