• 洛谷P1074 靶形数独(跳舞链)


    传送门

    坑着,等联赛之后再填(联赛挂了就不填了233)

      1 //minamoto
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<cstring>
      5 using namespace std;
      6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
      7 char buf[1<<21],*p1=buf,*p2=buf;
      8 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
      9 inline int read(){
     10     #define num ch-'0'
     11     char ch;bool flag=0;int res;
     12     while(!isdigit(ch=getc()))
     13     (ch=='-')&&(flag=true);
     14     for(res=num;isdigit(ch=getc());res=res*10+num);
     15     (flag)&&(res=-res);
     16     #undef num
     17     return res;
     18 }
     19 int score[100]={0,6,6,6,6,6,6,6,6,6,
     20 
     21                 6,7,7,7,7,7,7,7,6,
     22                 
     23                 6,7,8,8,8,8,8,7,6,
     24                 
     25                 6,7,8,9,9,9,8,7,6,
     26                 
     27                 6,7,8,9,10,9,8,7,6,
     28                 
     29                 6,7,8,9,9,9,8,7,6,
     30                 
     31                 6,7,8,8,8,8,8,7,6,
     32                 
     33                 6,7,7,7,7,7,7,7,6,
     34 
     35                 6,6,6,6,6,6,6,6,6};
     36 const int N=9,mm=N*N*N*N*N*4+N,mn=N*N*N+N;
     37 int mp[10][10];
     38 int ans=-1,sz;
     39 int U[mm],D[mm],L[mm],R[mm],C[mm],X[mm];
     40 int S[mn],Q[mn],H[mn];bool v[mn];
     41 void init(int r,int c){
     42     //建好虚拟节点 
     43     for(int i=0;i<=c;++i){
     44         S[i]=0,U[i]=D[i]=i,
     45         L[i+1]=i,R[i]=i+1;
     46     }
     47     R[sz=c]=0,L[0]=sz;
     48     while(r) H[r--]=-1;//判断每列是否有节点 
     49 }
     50 void place(int &r,int &c1,int &c2,int &c3,int &c4,int i,int j,int k){
     51     //看不懂 
     52     r=((i-1)*N+j-1)*N+k;
     53     c1=(i-1)*N+j;
     54     c2=N*N+(i-1)*N+k;
     55     c3=N*N*2+(j-1)*N+k;
     56     c4=N*N*3+(((i-1)/3)*3+(j-1)/3)*N+k;
     57 }
     58 void link(int r,int c){
     59     //S记录每列的元素个数,C是个队列,记录总的节点个数(大概) 
     60     //好像看不太懂这跳舞链怎么连的…… 
     61     ++S[C[++sz]=c];
     62     X[sz]=r,D[sz]=D[c],U[D[c]]=sz,
     63     U[sz]=c,D[c]=sz;
     64     if(H[r]==-1) H[r]=L[sz]=R[sz]=sz;//这行没有的话就都先连起来 
     65     else{
     66         R[sz]=R[H[r]],L[R[H[r]]]=sz,
     67         L[sz]=H[r],R[H[r]]=sz;
     68     }
     69 }
     70 void remove(int c){
     71     L[R[c]]=L[c],R[L[c]]=R[c];
     72     for(int i=D[c];i!=c;i=D[i])
     73     for(int j=R[i];j!=i;j=R[j])
     74     D[U[j]]=D[j],U[D[j]]=U[j],--S[C[j]];
     75 }
     76 void resume(int c){
     77     for(int i=U[c];i!=c;i=U[i])
     78     for(int j=L[i];j!=i;j=L[j])
     79     ++S[C[D[U[j]]=U[D[j]]=j]];
     80     L[R[c]]=R[L[c]]=c;
     81 }
     82 void dance(int k){
     83     if(!R[0]){
     84         int res=0;
     85         for(int i=0;i<k;++i)
     86         res+=score[(X[Q[i]]-1)/N+1]*((X[Q[i]]-1)%N+1);
     87         cmax(ans,res);
     88         return;
     89     }
     90     int tmp=mm,c;
     91     for(int i=R[0];i;i=R[i])
     92     if(S[i]<tmp) tmp=S[c=i];
     93     remove(c);
     94     for(int i=D[c];i!=c;i=D[i]){
     95         Q[k]=i;
     96         for(int j=R[i];j!=i;j=R[j]) remove(C[j]);
     97         dance(k+1);
     98         for(int j=L[i];j!=i;j=L[j]) resume(C[j]);
     99     }
    100     resume(c);
    101 }
    102 int main(){
    103 //    freopen("testdata.in","r",stdin);
    104     int r,c1,c2,c3,c4;
    105     init(mn,N*N*4);
    106     for(int i=1;i<=N;++i)
    107     for(int j=1;j<=N;++j){
    108         mp[i][j]=read();
    109         if(mp[i][j]){
    110             place(r,c1,c2,c3,c4,i,j,mp[i][j]);
    111             link(r,c1),link(r,c2),link(r,c3),link(r,c4);
    112             v[c1]=v[c2]=v[c3]=v[c4]=1;
    113         }
    114     }
    115     for(int i=1;i<=N;++i)
    116     for(int j=1;j<=N;++j)
    117     for(int k=1;k<=N;++k){
    118         place(r,c1,c2,c3,c4,i,j,k);
    119         if(v[c1]||v[c2]||v[c3]||v[c4])continue;
    120         link(r,c1),link(r,c2),link(r,c3),link(r,c4);
    121     }
    122     dance(0);
    123     printf("%d
    ",ans);
    124     return 0;
    125 }
  • 相关阅读:
    PHP设计模式——迭代模式
    采用navicat导出表结构及数据insert声明
    [Angular] Protect The Session Id with https and http only
    [D3] Creating a D3 Force Layout in React
    [D3] Animate Chart Axis Transitions in D3 v4
    [D3] Animate with the General Update Pattern in D3 v4
    [Web Security] JSON Hijacking
    [Angular] Progress HTTP Events with 'HttpRequest'
    [RxJS] How To get the results of two HTTP requests made in sequence
    [RxJS] Avoid mulit post requests by using shareReplay()
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9670705.html
Copyright © 2020-2023  润新知