• 愤怒的小鸟(爆搜,剪枝)


    题目描述

    Kiana 最近沉迷于一款神奇的游戏无法自拔。

    简单来说,这款游戏是在一个平面上进行的。

    有一架弹弓位于 (0,0)(0,0) 处,每次 Kiana 可以用它向第一象限发射一只红色的小鸟,小鸟们的飞行轨迹均为形如 y=ax^2+bxy=ax2+bx 的曲线,其中 a,ba,b 是Kiana 指定的参数,且必须满足 a < 0a<0 , a,ba,b 都是实数。

    当小鸟落回地面(即 xx 轴)时,它就会瞬间消失。

    在游戏的某个关卡里,平面的第一象限中有 nn 只绿色的小猪,其中第 ii 只小猪所在的坐标为 left(x_i,y_i ight)(xi,yi) 。

    如果某只小鸟的飞行轨迹经过了 left( x_i, y_i ight)(xi,yi) ,那么第 ii 只小猪就会被消灭掉,同时小鸟将会沿着原先的轨迹继续飞行;

    如果一只小鸟的飞行轨迹没有经过 left( x_i, y_i ight)(xi,yi) ,那么这只小鸟飞行的全过程就不会对第 ii 只小猪产生任何影响。

    例如,若两只小猪分别位于 (1,3)(1,3) 和 (3,3)(3,3) ,Kiana 可以选择发射一只飞行轨迹为 y=-x^2+4xy=x2+4x 的小鸟,这样两只小猪就会被这只小鸟一起消灭。

    而这个游戏的目的,就是通过发射小鸟消灭所有的小猪。

    这款神奇游戏的每个关卡对 Kiana来说都很难,所以Kiana还输入了一些神秘的指令,使得自己能更轻松地完成这个游戏。这些指令将在【输入格式】中详述。

    假设这款游戏一共有 TT 个关卡,现在 Kiana想知道,对于每一个关卡,至少需要发射多少只小鸟才能消灭所有的小猪。由于她不会算,所以希望由你告诉她。

    输入输出格式

    输入格式:

    第一行包含一个正整数 TT ,表示游戏的关卡总数。

    下面依次输入这 TT 个关卡的信息。每个关卡第一行包含两个非负整数 n,mn,m ,分别表示该关卡中的小猪数量和 Kiana 输入的神秘指令类型。接下来的 nn 行中,第 ii 行包含两个正实数 x_i,y_ixi,yi ,表示第 ii 只小猪坐标为 (x_i,y_i)(xi,yi) 。数据保证同一个关卡中不存在两只坐标完全相同的小猪。

    如果 m=0m=0 ,表示Kiana输入了一个没有任何作用的指令。

    如果 m=1m=1 ,则这个关卡将会满足:至多用 lceil n/3 + 1 ceiln/3+1⌉ 只小鸟即可消灭所有小猪。

    如果 m=2m=2 ,则这个关卡将会满足:一定存在一种最优解,其中有一只小鸟消灭了至少 lfloor n/3 floorn/3⌋ 只小猪。

    保证 1leq n leq 181n18 , 0leq m leq 20m2 , 0 < x_i,y_i < 100<xi,yi<10 ,输入中的实数均保留到小数点后两位。

    上文中,符号 lceil c ceilc⌉ 和 lfloor c floorc⌋ 分别表示对 cc 向上取整和向下取整,例如: lceil 2.1 ceil = lceil 2.9 ceil = lceil 3.0 ceil = lfloor 3.0 floor = lfloor 3.1 floor = lfloor 3.9 floor = 32.1=2.9=3.0=3.0=3.1=3.9=3 。

    输出格式:

    对每个关卡依次输出一行答案。

    输出的每一行包含一个正整数,表示相应的关卡中,消灭所有小猪最少需要的小鸟数量。

    思路:

    没什么好说的。。。只能%%一群状压大佬

    我是这么想的,一个猪被打掉,要么是单独的一只小鸟干的

    要么是被一只路过的小鸟干的

    那么,在经过一个没有被打掉的猪的时候,将这个猪与其他没有打掉的猪尝试配对

    算出一条抛物线,看这条路上能打掉几只猪,并打标记

    当然,也可以不算抛物线,默认用一只鸟打掉

    加一个最优化剪枝即可

    (ps 注意精度)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define rii register int i
    #define rij register int j
    #define inf 19260817
    #define eps 0.0000001
    using namespace std;
    int n,m,t,ans;
    struct pw{
        double a,b;
    }pwx[20];
    struct pig{
        double x,y;
    }zb[20];
    double bjx[20],bjy[20];
    inline pw echs(int wz,int i)
    {
        pw an;
        double lzn=zb[wz].x;
        double rxz=zb[wz].y;
        double ltt=(rxz*bjx[i]-bjy[i]*lzn);
        ltt/=(lzn*lzn*bjx[i]-bjx[i]*bjx[i]*lzn);
        double kkk=(rxz-lzn*lzn*ltt)/lzn;
        an.a=ltt;
        an.b=kkk;
        return an;
    }
    void dfs(int wz,int sl,int sy)
    {
        if(sl+sy>=ans)
        {
            return;
        }
        if(wz>=n+1)
        {
            ans=sl+sy;
            return;
        }
        int pd=0;
        for(rii=1;i<=sl;i++)
        {
            if(fabs(pwx[i].a*zb[wz].x*zb[wz].x+pwx[i].b*zb[wz].x-zb[wz].y)<=eps)
            {
                dfs(wz+1,sl,sy);
                pd=1;
                break;
            }
        }
        if(pd!=1)
        {
            for(rii=1;i<=sy;i++)
            {
                if(fabs(zb[wz].x-bjx[i])<eps)
                {
                    continue;
                }
                pw kk=echs(wz,i);
                if(kk.a<0)
                {   
                    pwx[sl+1]=kk;
                    double ltt=bjx[i];
                    double kkk=bjy[i];
                    for(rij=i;j<sy;j++)
                    {
                        bjx[j]=bjx[j+1];
                        bjy[j]=bjy[j+1];
                    }
                    dfs(wz+1,sl+1,sy-1);
                    for(rij=sy;j>i;j--) 
                    {
                        bjx[j]=bjx[j-1];
                        bjy[j]=bjy[j-1];
                    }
                    bjx[i]=ltt;
                    bjy[i]=kkk;
                }
            }
            bjx[sy+1]=zb[wz].x;
            bjy[sy+1]=zb[wz].y;
            dfs(wz+1,sl,sy+1);
        }
    }
    int main()
    {
        scanf("%d",&t);
        for(rii=1;i<=t;i++)
        {
            scanf("%d%d",&n,&m);
            for(rij=1;j<=n;j++)
            {
                scanf("%lf%lf",&zb[j].x,&zb[j].y);
            }
            ans=inf;
            dfs(1,0,0);
            printf("%d
    ",ans); 
        } 
    }
  • 相关阅读:
    正则表达式验证银行卡号
    正则表达式验证银行卡号
    正则表达式验证手机号
    正则表达式验证手机号
    好用的手机浏览器
    jmeter(三)跨线程组调用token
    jmeter(二)ant报告模板下载与使用
    1-5JSON数据解析
    1-3HTTP协议基础
    1-2接口测试概述
  • 原文地址:https://www.cnblogs.com/ztz11/p/9401434.html
Copyright © 2020-2023  润新知