zoukankan      html  css  js  c++  java
  • bzoj2515 Room

    Description

    Input

    Output

    折半搜索,用散列表记录从原点出发,用了S(状压表示)这几种边(令|S|*2-1<=n),到达(x,y)的最大面积。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    int ps[301][8][2],pp[301],r[10],n,ed[10],st=0,ans;
    #define cal(w,x,y,a,b,s) dfs(w,x+(a),y+(b),s+x*(b)-y*(a))
    const int P=1844677;
    int h[P][4],ht=0,ds[32];
    void maxs(int&a,int b){if(a<b)a=b;}
    void mins(int&a,int b){if(a>b)a=b;}
    void ins(int st,int x,int y,int s){
        int X,w,st2=(1<<n)-1-st;
        if(ds[st2]==ht){
            X=(x+1024<<11|y+1024)<<6|st2;
            w=X%P;
            while(h[w][0]==ht){
                if(h[w][1]==X){
                    maxs(ans,h[w][2]+s);
                    break;
                }
                if((w+=1237)>=P)w-=P;
            }
        }else{
            ds[st]=ht;
            X=(x+1024<<11|y+1024)<<6|st;
            w=X%P;
            while(h[w][0]==ht){
                if(h[w][1]==X){
                    maxs(h[w][2],s);
                    return;
                }
                if((w+=1237)>=P)w-=P;
            }
            h[w][0]=ht;
            h[w][1]=X;
            h[w][2]=s;
        }
    }
    void dfs(int w,int x,int y,int s){
        if(w)ins(st,x,y,s);
        if(w<3)
        for(int i=0;i<n;++i)if(!ed[i]){
            ed[i]=1;
            st^=1<<i;
            int v=r[i];
            for(int j=0;j<pp[v];++j){
                int a=ps[v][j][0],b=ps[v][j][1];
                cal(w+1,x,y,a,b,s);
                cal(w+1,x,y,a,-b,s);
                cal(w+1,x,y,-a,b,s);
                cal(w+1,x,y,-a,-b,s);
                cal(w+1,x,y,b,a,s);
                cal(w+1,x,y,b,-a,s);
                cal(w+1,x,y,-b,a,s);
                cal(w+1,x,y,-b,-a,s);
            }
            st^=1<<i;
            ed[i]=0;
        }
    }
    int main(){
        for(int i=1;i<=300;++i){
            for(int j=0;j*j*2<=i*i;++j){
                int z=sqrt(i*i-j*j)+1e-10;
                if(j*j+z*z==i*i)ps[i][pp[i]][0]=j,ps[i][pp[i]++][1]=z;
            }
        }
        while(scanf("%d",&n)==1&&n){
            for(int i=0;i<n;++i)scanf("%d",r+i);
            ans=0;
            ++ht;
            dfs(0,0,0,0);
            if(!ans)puts("-1");
            else if(~ans&1)printf("%d
    ",ans>>1);
            else printf("%d.5
    ",ans>>1);
        }
        return 0;
    }
  • 相关阅读:
    递归函数底层原理浅析
    lambda expression & mutable
    命令mv
    printf的参数
    程序结构之静态本地变量
    汇编.align指令
    程序结构之全局变量
    命令touch
    更改gcc默认版本,实现gcc版本升降级
    命令chmod
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6212579.html
Copyright © 2011-2022 走看看