p1460

  终于A掉了noip2016的Day2T3,至此,2015和2016的NOIP题都刷完了.

  

  写一下这道题卡常的过程吧.

  真的只需要卡常啊.

  

  

  m不用管了,反正奔着AC去的.

  考虑怎么搜索?我们可以n^2的枚举所有的抛物线,再O(n)的枚举这条抛物线可以打掉哪些小猪.用一个二进制数存一下状态.

  然后把所有的状态入队,答案设为1,然后开始bfs啦.

  我们需要一些常数优化即可A掉本题.

struct node 
{
    double x,y;
}o[20];
int tot,T,n,m,now,t;
double a,b,eps=1e-10;
double geta(node a,node b)
{
    return (a.y*b.x/a.x-b.y)/(b.x*a.x-b.x*b.x);
}
double getb(double a,node b)
{
    return b.y/b.x-a*b.x;
}
int can[1<<20],ans[1<<20];
bool v[1<<20];
queue<int>q;
inline void write(int x){
    if(x==0){
        putchar('0');        
        return;
    }
    if(x<0){
        putchar('-');
        x=-x;
    }
    int num=0;char ch[16];
    while(x) ch[++num]=x%10+'0',x/=10;
    while(num) putchar(ch[num--]);    
}
int main()
{
    for(scanf("%d",&T);T;--T)
    {
        scanf("%d%d",&n,&m);//久违的用scanf读入 
        for(register int i=1;i<=n;++i)//吹爆register! 
            scanf("%lf%lf",&o[i].x,&o[i].y);
        tot=0;
        for(register int i=1;i<=n;++i)
        {
            tot++;
            can[tot]=1<<i;//显然至少可以把i覆盖了 
            for(register int f=i+1;f<=n;++f)
            {
                a=geta(o[i],o[f]);
                if(a>=-eps)//如果a是负数就不要 
                    continue;
                b=getb(a,o[i]);
                tot++;can[tot]=0;
                for(register int j=1;j<=n;j++)
                    if(fabs(a*o[j].x*o[j].x+b*o[j].x-o[j].y)<=eps)
                        can[tot]|=1<<j;
            }
        }
        int f=1<<(n+1); 
        for(register int i=1;i<=f;++i)
            ans[i]=10;
        for(register int i=1;i<=tot;++i)
        {
            q.push(can[i]);
            ans[can[i]]=1;
            v[can[i]]=1;
        }
        while(q.size())
        {
            now=q.front();q.pop();
            for(register int i=1;i<=tot;++i)
            {
                t=now|can[i];
                if(v[t])continue;
                if(t>now&&ans[now]+1<ans[t])
                {
                    ans[t]=ans[now]+1;
                    q.push(t);
                    v[t]=1;
                }
            }
            v[now]=0;
        }
        write(ans[(1<<n+1)-2]);
        putchar(10);
    }    
}
View Code

  吹爆register好吧,TLE秒变AC.(其实T掉的在本地跑也就是1.1s...)

>>>

原文地址:https://www.cnblogs.com/qywyt/p/10424299.html