• [kuangbin带你飞]专题三 Dancing Links


    https://vjudge.net/contest/65998#overview

    https://blog.csdn.net/whereisherofrom/article/details/79188290

    https://www.cnblogs.com/jh818012/p/3252154.html

    https://blog.csdn.net/qq_40889820/article/details/99840204

    A、Exact cover

    此题已挂,模板题

    B、Treasure Map

    注意坐标转换吧(TLE了一上午)。。

      1 #include<iostream>
      2 #include<sstream>
      3 #include<fstream>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<iomanip>
      7 #include<cstdlib>
      8 #include<cctype>
      9 #include<vector>
     10 #include<string>
     11 #include<cmath>
     12 #include<ctime>
     13 #include<stack>
     14 #include<queue>
     15 #include<map>
     16 #include<set>
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define random(a,b) (rand()%(b-a+1)+a)
     19 #define ll long long
     20 #define ull unsigned long long
     21 #define e 2.71828182
     22 #define Pi acos(-1.0)
     23 #define ls(rt) (rt<<1)
     24 #define rs(rt) (rt<<1|1)
     25 #define lowbit(x) (x&(-x))
     26 using namespace std;
     27 const int MAXN=6e5+5;
     28 const int INF=0x3f3f3f3f;
     29 int read()
     30 {
     31     int s=1,x=0;
     32     char ch=getchar();
     33     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
     34     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
     35     return x*s;
     36 }
     37 struct DLX
     38 {
     39     int n,m,cnt,g;
     40     int U[MAXN],D[MAXN],R[MAXN],L[MAXN],row[MAXN],col[MAXN];
     41     int H[MAXN],S[MAXN];
     42     void init(int _n,int _m)
     43     {
     44         n=_n,m=_m;g=INF;
     45         for(int i=0;i<=m;++i)
     46         S[i]=0,U[i]=D[i]=i,L[i]=i-1,R[i]=i+1;
     47         R[m]=0,L[0]=m,cnt=m;
     48         for(int i=1;i<=n;++i)
     49         H[i]=-1;
     50     }
     51     void add(int r,int c)
     52     {
     53         ++S[col[++cnt]=c];
     54         row[cnt]=r;
     55         D[cnt]=D[c],U[D[c]]=cnt;
     56         U[cnt]=c,D[c]=cnt;
     57         if(H[r]<0) H[r]=L[cnt]=R[cnt]=cnt;
     58         else R[cnt]=R[H[r]],L[R[H[r]]]=cnt,L[cnt]=H[r],R[H[r]]=cnt;
     59     }
     60     void remove(int c)
     61     {
     62         L[R[c]]=L[c],R[L[c]]=R[c];
     63         for(int i=D[c];i!=c;i=D[i])
     64         for(int j=R[i];j!=i;j=R[j])
     65         U[D[j]]=U[j],D[U[j]]=D[j],--S[col[j]];
     66     }
     67     void resume(int c)
     68     {
     69         for(int i=U[c];i!=c;i=U[i])
     70         for(int j=L[i];j!=i;j=L[j])
     71         ++S[col[U[D[j]]=D[U[j]]=j]];
     72         L[R[c]]=R[L[c]]=c;
     73     }
     74     void dance(int k)
     75     {
     76         if(k-1>=g) return;    
     77         if(R[0]==0)
     78         {
     79             g=k-1;
     80             return;
     81         }
     82         int c=R[0];
     83         for(int i=R[0];i!=0;i=R[i])
     84         if(S[i]<S[c]) c=i;
     85         remove(c);
     86         for(int i=D[c];i!=c;i=D[i])
     87         {
     88             for(int j=R[i];j!=i;j=R[j]) remove(col[j]);
     89             dance(k+1);
     90             for(int j=L[i];j!=i;j=L[j]) resume(col[j]);
     91         }
     92         resume(c);
     93         return ;
     94     }
     95 }dlx;
     96 int main()
     97 {
     98     int test=read();
     99     while(test--)
    100     {
    101         int n=read(),m=read(),q=read();
    102         dlx.init(q,n*m);
    103         for(int k=1;k<=q;++k)
    104         {
    105             int x1=read()+1,y1=read()+1,x2=read(),y2=read();
    106             for(int i=x1;i<=x2;++i)
    107             for(int j=y1;j<=y2;++j)
    108             dlx.add(k,(j-1)*n+i);
    109         }
    110         dlx.dance(1);
    111         if(dlx.g==INF) puts("-1");
    112         else cout<<dlx.g<<endl;
    113     }
    114     return 0;
    115 }
    View Code

    C、Radar

    n座城,m个雷达站,最多安k个雷达,问安装雷达的最小半径使得n座城都在雷达范围内。

    二分雷达的半径,判定最多k个雷达半径为r时能否覆盖到n座城,判定函数中用DLX求重复覆盖。

    DLX中每一行代表一个雷达和n座城的覆盖关系。

    注意精确覆盖和重复覆盖模板中有区别。

      1 #include<iostream>
      2 #include<sstream>
      3 #include<fstream>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<iomanip>
      7 #include<cstdlib>
      8 #include<cctype>
      9 #include<vector>
     10 #include<string>
     11 #include<cmath>
     12 #include<ctime>
     13 #include<stack>
     14 #include<queue>
     15 #include<map>
     16 #include<set>
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define random(a,b) (rand()%(b-a+1)+a)
     19 #define ll long long
     20 #define ull unsigned long long
     21 #define e 2.71828182
     22 #define Pi acos(-1.0)
     23 #define ls(rt) (rt<<1)
     24 #define rs(rt) (rt<<1|1)
     25 #define lowbit(x) (x&(-x))
     26 using namespace std;
     27 const int MAXN=50+5;
     28 const int MAXM=50+5;
     29 const int MAX=3000+5;
     30 const int INF=0x3f3f3f3f;
     31 const double eps=1e-8;
     32 int read()
     33 {
     34     int s=1,x=0;
     35     char ch=getchar();
     36     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
     37     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
     38     return x*s;
     39 }
     40 int K,M,N;
     41 struct DLX
     42 {
     43     int n,m,cnt;
     44     int U[MAX],D[MAX],R[MAX],L[MAX],row[MAX],col[MAX];
     45     int H[MAXN],S[MAXM];
     46     bool v[MAX];
     47     void init(int _n,int _m)
     48     {
     49         n=_n,m=_m;
     50         for(int i=0;i<=m;++i)
     51         S[i]=0,U[i]=D[i]=i,L[i]=i-1,R[i]=i+1;
     52         R[m]=0,L[0]=m,cnt=m;
     53         mem(H,-1);
     54     }
     55     void add(int r,int c)
     56     {
     57         ++S[col[++cnt]=c];
     58         row[cnt]=r;
     59         D[cnt]=D[c],U[D[c]]=cnt;
     60         U[cnt]=c,D[c]=cnt;
     61         if(H[r]<0) H[r]=L[cnt]=R[cnt]=cnt;
     62         else R[cnt]=R[H[r]],L[R[H[r]]]=cnt,L[cnt]=H[r],R[H[r]]=cnt;
     63     }
     64     void remove(int c)
     65     {
     66         for(int i=D[c];i!=c;i=D[i])
     67         L[R[i]]=L[i],R[L[i]]=R[i];
     68     }
     69     void resume(int c)
     70     {
     71         for(int i=U[c];i!=c;i=U[i])
     72         L[R[i]]=R[L[i]]=i;
     73     }
     74     int h()
     75     {
     76         int ret=0;
     77         for(int i=R[0];i!=0;i=R[i]) v[i]=true;
     78         for(int i=R[0];i!=0;i=R[i])
     79         {
     80             if(!v[i]) continue;
     81             ret++,v[i]=false;
     82             for(int j=D[i];j!=i;j=D[j])
     83             for(int k=R[j];k!=j;k=R[k])
     84             v[col[k]]=false;
     85         }    
     86         return ret;
     87     } 
     88     bool dance(int d)
     89     {
     90         if(d+h()>K) return false;
     91         if(R[0]==0)
     92         {
     93             return d<=K;
     94         }
     95         int c=R[0];
     96         for(int i=R[0];i!=0;i=R[i])
     97         if(S[i]<S[c]) c=i;
     98         for(int i=D[c];i!=c;i=D[i])
     99         {
    100             remove(i);
    101             for(int j=R[i];j!=i;j=R[j]) remove(j);
    102             if(dance(d+1)) return true;
    103             for(int j=L[i];j!=i;j=L[j]) resume(j);
    104             resume(i);
    105         }
    106         return false;
    107     }
    108 }dlx;
    109 struct Point
    110 {
    111     int x,y;
    112     void input()
    113     {
    114         x=read(),y=read();
    115     }
    116 }city[MAXN],radar[MAXM];
    117 double dis(Point a,Point b)
    118 {
    119     return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y));
    120 }
    121 bool C(double r)
    122 {
    123     dlx.init(M,N);
    124     for(int i=1;i<=M;++i)
    125     {
    126         for(int j=1;j<=N;++j)
    127         {
    128             if(dis(radar[i],city[j])<r-eps) 
    129             dlx.add(i,j);
    130         }
    131     } 
    132     return dlx.dance(0);
    133 }
    134 int main()
    135 {
    136     int test=read();
    137     while(test--)
    138     {
    139         N=read(),M=read(),K=read();
    140         for(int i=1;i<=N;++i) city[i].input();
    141         for(int i=1;i<=M;++i) radar[i].input();
    142         double lb=0,ub=INF;
    143         for(int i=0;i<100;++i)
    144         {        
    145             double mid=(lb+ub)/2;
    146             if(C(mid)) ub=mid;
    147             else lb=mid;
    148         }
    149         cout<<setiosflags(ios::fixed)<<setprecision(6)<<lb<<endl;
    150     }
    151 }
    View Code

    D、神龙的难题

    一次操作能将n1*m1的元素变为0,问将n*m的元素全部变为0(有一些原先就是0)最少的操作数。

    将原来n*m的元素中为1的作为列,枚举每次操作的左上角作为行,重复覆盖的最小值。

    注意剪枝!!!(有个地方不加等于就超时了)

    注意MAXM、MAXN、MAX的定义!!不要开小了,不然会死循环?

      1 #include<iostream>
      2 #include<sstream>
      3 #include<fstream>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<iomanip>
      7 #include<cstdlib>
      8 #include<cctype>
      9 #include<vector>
     10 #include<string>
     11 #include<cmath>
     12 #include<ctime>
     13 #include<stack>
     14 #include<queue>
     15 #include<map>
     16 #include<set>
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define random(a,b) (rand()%(b-a+1)+a)
     19 #define ll long long
     20 #define ull unsigned long long
     21 #define e 2.71828182
     22 #define Pi acos(-1.0)
     23 #define ls(rt) (rt<<1)
     24 #define rs(rt) (rt<<1|1)
     25 #define lowbit(x) (x&(-x))
     26 using namespace std;
     27 const int MAXM=15*15;
     28 const int MAXN=15*15;
     29 const int MAX=400*400;
     30 int read()
     31 {
     32     int s=1,x=0;
     33     char ch=getchar();
     34     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
     35     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
     36     return x*s;
     37 }
     38 int N,M,N1,M1;
     39 struct DLX
     40 {
     41     int n,m,cnt,ansd;
     42     int U[MAX],D[MAX],R[MAX],L[MAX],row[MAX],col[MAX];
     43     int H[MAXN],S[MAXM];
     44     bool v[MAX];
     45     void init(int _n,int _m)
     46     {
     47         n=_n,m=_m,ansd=1<<30;
     48         for(int i=0;i<=m;++i)
     49         S[i]=0,U[i]=D[i]=i,L[i]=i-1,R[i]=i+1;
     50         R[m]=0,L[0]=m,cnt=m;
     51         mem(H,-1);
     52     }
     53     void add(int r,int c)
     54     {
     55         ++S[col[++cnt]=c];
     56         row[cnt]=r;
     57         D[cnt]=D[c],U[D[c]]=cnt;
     58         U[cnt]=c,D[c]=cnt;
     59         if(H[r]<0) H[r]=L[cnt]=R[cnt]=cnt;
     60         else R[cnt]=R[H[r]],L[R[H[r]]]=cnt,L[cnt]=H[r],R[H[r]]=cnt;
     61     }
     62     void remove(int c)
     63     {
     64         for(int i=D[c];i!=c;i=D[i])
     65         L[R[i]]=L[i],R[L[i]]=R[i];
     66     }
     67     void resume(int c)
     68     {
     69         for(int i=U[c];i!=c;i=U[i])
     70         L[R[i]]=R[L[i]]=i;
     71     }
     72     int h()
     73     {
     74         int ret=0;
     75         for(int i=R[0];i!=0;i=R[i]) v[i]=true;
     76         for(int i=R[0];i!=0;i=R[i])
     77         {
     78             if(!v[i]) continue;
     79             ret++,v[i]=false;
     80             for(int j=D[i];j!=i;j=D[j])
     81             for(int k=R[j];k!=j;k=R[k])
     82             v[col[k]]=false;
     83         }    
     84         return ret;
     85     } 
     86     void dance(int d)
     87     {
     88         if(d+h()>=ansd) return;
     89         if(R[0]==0)
     90         {
     91             if(d<ansd) ansd=d;
     92             return ;
     93         }
     94         int c=R[0];
     95         for(int i=R[0];i!=0;i=R[i])
     96         if(S[i]<S[c]) c=i;
     97         for(int i=D[c];i!=c;i=D[i])
     98         {
     99             remove(i);
    100             for(int j=R[i];j!=i;j=R[j]) remove(j);
    101             (dance(d+1));
    102             for(int j=L[i];j!=i;j=L[j]) resume(j);
    103             resume(i);
    104         }
    105         return ;
    106     }
    107 }dlx;
    108 struct monster
    109 {
    110     int x,y;
    111     void set_xy(int _x,int _y)
    112     {
    113         x=_x,y=_y;
    114     }
    115 }Mon[MAXN];
    116 int main()
    117 {
    118     while(~scanf("%d%d",&N,&M))
    119     {
    120         int cnt1=0,cnt2=0;
    121         for(int i=1;i<=N;++i)
    122         for(int j=1;j<=M;++j)
    123         if(read()) Mon[++cnt1].set_xy(i,j);
    124         
    125         N1=read(),M1=read();
    126         dlx.init((N-N1+1)*(M-M1+1),cnt1);
    127         
    128         for(int i=1;i<=N;++i)
    129         for(int j=1;j<=M;++j)
    130         {
    131             bool flag=false;
    132             for(int k=1;k<=cnt1;++k)
    133             if(Mon[k].x>=i&&Mon[k].x<=i+N1-1&&Mon[k].y>=j&&Mon[k].y<=j+M1-1)
    134             {
    135                 if(!flag) dlx.add(++cnt2,k),flag=true;
    136                 else dlx.add(cnt2,k);
    137                 //dlx.add((i-1)*M+j,k);
    138             }
    139         }
    140     
    141         dlx.dance(0);
    142         cout<<dlx.ansd<<"
    ";
    143     }
    144 }
    View Code

    有时为了避免麻烦,可以添加空行进去

      1 #include<iostream>
      2 #include<sstream>
      3 #include<fstream>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<iomanip>
      7 #include<cstdlib>
      8 #include<cctype>
      9 #include<vector>
     10 #include<string>
     11 #include<cmath>
     12 #include<ctime>
     13 #include<stack>
     14 #include<queue>
     15 #include<map>
     16 #include<set>
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define random(a,b) (rand()%(b-a+1)+a)
     19 #define ll long long
     20 #define ull unsigned long long
     21 #define e 2.71828182
     22 #define Pi acos(-1.0)
     23 #define ls(rt) (rt<<1)
     24 #define rs(rt) (rt<<1|1)
     25 #define lowbit(x) (x&(-x))
     26 using namespace std;
     27 const int MAXM=233;
     28 const int MAXN=233;
     29 const int MAX=400*400;
     30 int read()
     31 {
     32     int s=1,x=0;
     33     char ch=getchar();
     34     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
     35     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
     36     return x*s;
     37 }
     38 int N,M,N1,M1;
     39 struct DLX
     40 {
     41     int n,m,cnt,ansd;
     42     int U[MAX],D[MAX],R[MAX],L[MAX],row[MAX],col[MAX];
     43     int H[MAXN],S[MAXM];
     44     bool v[MAX];
     45     void init(int _n,int _m)
     46     {
     47         n=_n,m=_m,ansd=1<<30;
     48         for(int i=0;i<=m;++i)
     49         S[i]=0,U[i]=D[i]=i,L[i]=i-1,R[i]=i+1;
     50         R[m]=0,L[0]=m,cnt=m;
     51         mem(H,-1);
     52     }
     53     void add(int r,int c)
     54     {
     55         ++S[col[++cnt]=c];
     56         row[cnt]=r;
     57         D[cnt]=D[c],U[D[c]]=cnt;
     58         U[cnt]=c,D[c]=cnt;
     59         if(H[r]<0) H[r]=L[cnt]=R[cnt]=cnt;
     60         else R[cnt]=R[H[r]],L[R[H[r]]]=cnt,L[cnt]=H[r],R[H[r]]=cnt;
     61     }
     62     void remove(int c)
     63     {
     64         for(int i=D[c];i!=c;i=D[i])
     65         L[R[i]]=L[i],R[L[i]]=R[i];
     66     }
     67     void resume(int c)
     68     {
     69         for(int i=U[c];i!=c;i=U[i])
     70         L[R[i]]=R[L[i]]=i;
     71     }
     72     int h()
     73     {
     74         int ret=0;
     75         for(int i=R[0];i!=0;i=R[i]) v[i]=true;
     76         for(int i=R[0];i!=0;i=R[i])
     77         {
     78             if(!v[i]) continue;
     79             ret++,v[i]=false;
     80             for(int j=D[i];j!=i;j=D[j])
     81             for(int k=R[j];k!=j;k=R[k])
     82             v[col[k]]=false;
     83         }    
     84         return ret;
     85     } 
     86     void dance(int d)
     87     {
     88         if(d+h()>=ansd) return;
     89         if(R[0]==0)
     90         {
     91             if(d<ansd) ansd=d;
     92             return ;
     93         }
     94         int c=R[0];
     95         for(int i=R[0];i!=0;i=R[i])
     96         if(S[i]<S[c]) c=i;
     97         for(int i=D[c];i!=c;i=D[i])
     98         {
     99             remove(i);
    100             for(int j=R[i];j!=i;j=R[j]) remove(j);
    101             dance(d+1);
    102             for(int j=L[i];j!=i;j=L[j]) resume(j);
    103             resume(i);
    104         }
    105         return ;
    106     }
    107 }dlx;
    108 struct monster
    109 {
    110     int x,y;
    111     void set_xy(int _x,int _y)
    112     {
    113         x=_x,y=_y;
    114     }
    115 }Mon[MAXN];
    116 int main() {
    117     while(~scanf("%d%d",&N,&M))
    118     {
    119         int cnt1=0,cnt2=0;
    120         for(int i=1;i<=N;++i)
    121         for(int j=1;j<=M;++j)
    122         if(read()) Mon[++cnt1].set_xy(i,j);
    123         
    124         N1=read(),M1=read();
    125         dlx.init(N*M,cnt1);
    126         
    127         for(int i=1;i<=N;++i)
    128         for(int j=1;j<=M;++j)
    129         for(int k=1;k<=cnt1;++k)
    130         if(Mon[k].x>=i&&Mon[k].x<=i+N1-1&&Mon[k].y>=j&&Mon[k].y<=j+M1-1)
    131         dlx.add((i-1)*M+j,k);
    132         
    133         dlx.dance(0);
    134         cout<<dlx.ansd<<"
    ";
    135     }
    136 }
    View Code

    E、Square Destroyer

    2*n*(n+1)根火柴棒组成下图边长为n的由正方形(n<=5)

    编号如图,给定一个完整或不完整的图,求拿走火柴棒的最少根数,使得图中不存在任何一个完整的正方形。

    思路:将火柴棒的编号作为行,不同正方形的编号作为列,将每一根火柴棒能破坏的正方形记录,建立DLX,即求解重复覆盖

    处理起来蛮麻烦的,好在n的范围是[1,5]

    对于边长为n的图,存在边长为n的正方形1个,边长为n-1的正方形4(22)个,边长为n-2的正方形9(32)个,,,边长为1的正方形n2个,即n(n+1)(2n+1)/6个正方形。

    又火柴棒数为2n(n+1)个。

    即为2n(n+1)行,n(n+1)(2n+1)/6列。

    代码就不写了,有、烦。

    F、Sudoku

    9*9数独,转化为精确覆盖问题

      1 #include<iostream>
      2 #include<sstream>
      3 #include<fstream>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<iomanip>
      7 #include<cstdlib>
      8 #include<cctype>
      9 #include<vector>
     10 #include<string>
     11 #include<cmath>
     12 #include<ctime>
     13 #include<stack>
     14 #include<queue>
     15 #include<map>
     16 #include<set>
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define random(a,b) (rand()%(b-a+1)+a)
     19 #define ll long long
     20 #define ull unsigned long long
     21 #define e 2.71828182
     22 #define Pi acos(-1.0)
     23 #define ls(rt) (rt<<1)
     24 #define rs(rt) (rt<<1|1)
     25 #define lowbit(x) (x&(-x))
     26 using namespace std;
     27 const int MAXN=777;//9*9*9
     28 const int MAXM=333;//9*9*4
     29 const int MAX=4e5+5;
     30 char str[92];
     31 struct DLX
     32 {
     33     int n,m,cnt,g;
     34     int U[MAX],D[MAX],R[MAX],L[MAX],row[MAX],col[MAX];
     35     int H[MAXN],S[MAXM],ans[MAXN];
     36     void init(int _n,int _m)
     37     {
     38         n=_n,m=_m,g=0;
     39         for(int i=0;i<=m;++i)
     40         S[i]=0,U[i]=D[i]=i,L[i]=i-1,R[i]=i+1;
     41         R[m]=0,L[0]=m,cnt=m;
     42         for(int i=1;i<=n;++i)
     43         H[i]=-1;
     44     }
     45     void add(int r,int c)
     46     {
     47         ++S[col[++cnt]=c];
     48         row[cnt]=r;
     49         D[cnt]=D[c],U[D[c]]=cnt;
     50         U[cnt]=c,D[c]=cnt;
     51         if(H[r]<0) H[r]=L[cnt]=R[cnt]=cnt;
     52         else R[cnt]=R[H[r]],L[R[H[r]]]=cnt,L[cnt]=H[r],R[H[r]]=cnt;
     53     }
     54     void remove(int c)
     55     {
     56         L[R[c]]=L[c],R[L[c]]=R[c];
     57         for(int i=D[c];i!=c;i=D[i])
     58         for(int j=R[i];j!=i;j=R[j])
     59         U[D[j]]=U[j],D[U[j]]=D[j],--S[col[j]];
     60     }
     61     void resume(int c)
     62     {
     63         for(int i=U[c];i!=c;i=U[i])
     64         for(int j=L[i];j!=i;j=L[j])
     65         ++S[col[U[D[j]]=D[U[j]]=j]];
     66         L[R[c]]=R[L[c]]=c;
     67     }
     68     bool dance(int k)
     69     {  
     70         if(R[0]==0)
     71         {
     72             g=k-1;
     73             return true;
     74         }
     75         int c=R[0];
     76         for(int i=R[0];i!=0;i=R[i])
     77         if(S[i]<S[c]) c=i;
     78         remove(c);
     79         for(int i=D[c];i!=c;i=D[i])
     80         {
     81             for(int j=R[i];j!=i;j=R[j]) remove(col[j]);
     82             ans[k]=row[i];
     83             if(dance(k+1)) return true;
     84             for(int j=L[i];j!=i;j=L[j]) resume(col[j]);
     85         }
     86         resume(c);
     87         return false;
     88     }
     89 }dlx;
     90 int read()
     91 {
     92     int s=1,x=0;
     93     char ch=getchar();
     94     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
     95     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
     96     return x*s;
     97 }
     98 struct node
     99 {
    100     int x,y,num;
    101 }data[MAXN];
    102 int f(int i,int j)//第几宫 
    103 {
    104     return ((i-1)/3)*3+(j+2)/3;
    105 }
    106 int main()
    107 {
    108     int t;
    109     while(true)
    110     {
    111         int cur=0;
    112         scanf("%s",str+1);
    113         if(str[1]=='e') break;
    114         dlx.init(729,324);
    115         for(int i=1;i<=9;++i)
    116         {
    117             for(int j=1;j<=9;++j)
    118             {
    119                 if(str[(i-1)*9+j]=='.') 
    120                 {
    121                     for(t=1;t<=9;++t)
    122                     {
    123                         dlx.add(++cur,(i-1)*9+j);
    124                         dlx.add(cur,81+(i-1)*9+t);
    125                         dlx.add(cur,81*2+(j-1)*9+t);
    126                         dlx.add(cur,81*3+(f(i,j)-1)*9+t);
    127                         data[cur].x=i,data[cur].y=j,data[cur].num=t;//保存每行的数据 
    128                     }
    129                 }
    130                 else
    131                 {
    132                     t=str[(i-1)*9+j]-'0';
    133                     dlx.add(++cur,(i-1)*9+j);
    134                     dlx.add(cur,81+(i-1)*9+t);
    135                     dlx.add(cur,81*2+(j-1)*9+t);
    136                     dlx.add(cur,81*3+(f(i,j)-1)*9+t);
    137                     data[cur].x=i,data[cur].y=j,data[cur].num=t;     
    138                 } 
    139             }
    140         }
    141         if(!dlx.dance(1)) exit(-1);
    142         //cout<<dlx.g<<endl;
    143         for(int i=1;i<=81;++i)
    144         {
    145             int idx=(data[dlx.ans[i]].x-1)*9+data[dlx.ans[i]].y;
    146             str[idx]=data[dlx.ans[i]].num+'0';
    147         }
    148         cout<<str+1<<endl;
    149     }
    150 }
    View Code

    G、Sudoku

    16*16数独,同上

    这题数据太坑,样例输入错了,还要注意有多组数据,每组的输出要多加一个换行

      1 #include<iostream>
      2 #include<sstream>
      3 #include<fstream>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<iomanip>
      7 #include<cstdlib>
      8 #include<cctype>
      9 #include<vector>
     10 #include<string>
     11 #include<cmath>
     12 #include<ctime>
     13 #include<stack>
     14 #include<queue>
     15 #include<map>
     16 #include<set>
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define random(a,b) (rand()%(b-a+1)+a)
     19 #define ll long long
     20 #define ull unsigned long long
     21 #define e 2.71828182
     22 #define Pi acos(-1.0)
     23 #define ls(rt) (rt<<1)
     24 #define rs(rt) (rt<<1|1)
     25 #define lowbit(x) (x&(-x))
     26 using namespace std;
     27 const int MAXN=4100;//16*16*16
     28 const int MAXM=1100;//16*16*4
     29 const int MAX=5e6+5;
     30 char str[17][17];
     31 struct DLX
     32 {
     33     int n,m,cnt,g;
     34     int U[MAX],D[MAX],R[MAX],L[MAX],row[MAX],col[MAX];
     35     int H[MAXN],S[MAXM],ans[MAXN];
     36     void init(int _n,int _m)
     37     {
     38         n=_n,m=_m,g=0;
     39         for(int i=0;i<=m;++i)
     40         S[i]=0,U[i]=D[i]=i,L[i]=i-1,R[i]=i+1;
     41         R[m]=0,L[0]=m,cnt=m;
     42         for(int i=1;i<=n;++i)
     43         H[i]=-1;
     44     }
     45     void add(int r,int c)
     46     {
     47         ++S[col[++cnt]=c];
     48         row[cnt]=r;
     49         D[cnt]=D[c],U[D[c]]=cnt;
     50         U[cnt]=c,D[c]=cnt;
     51         if(H[r]<0) H[r]=L[cnt]=R[cnt]=cnt;
     52         else R[cnt]=R[H[r]],L[R[H[r]]]=cnt,L[cnt]=H[r],R[H[r]]=cnt;
     53     }
     54     void remove(int c)
     55     {
     56         L[R[c]]=L[c],R[L[c]]=R[c];
     57         for(int i=D[c];i!=c;i=D[i])
     58         for(int j=R[i];j!=i;j=R[j])
     59         U[D[j]]=U[j],D[U[j]]=D[j],--S[col[j]];
     60     }
     61     void resume(int c)
     62     {
     63         for(int i=U[c];i!=c;i=U[i])
     64         for(int j=L[i];j!=i;j=L[j])
     65         ++S[col[U[D[j]]=D[U[j]]=j]];
     66         L[R[c]]=R[L[c]]=c;
     67     }
     68     bool dance(int k)
     69     {  
     70         if(R[0]==0)
     71         {
     72             g=k-1;
     73             return true;
     74         }
     75         int c=R[0];
     76         for(int i=R[0];i!=0;i=R[i])
     77         if(S[i]<S[c]) c=i;
     78         remove(c);
     79         for(int i=D[c];i!=c;i=D[i])
     80         {
     81             for(int j=R[i];j!=i;j=R[j]) remove(col[j]);
     82             ans[k]=row[i];
     83             if(dance(k+1)) return true;
     84             for(int j=L[i];j!=i;j=L[j]) resume(col[j]);
     85         }
     86         resume(c);
     87         return false;
     88     }
     89 }dlx;
     90 int read()
     91 {
     92     int s=1,x=0;
     93     char ch=getchar();
     94     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
     95     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
     96     return x*s;
     97 }
     98 struct node
     99 {
    100     int x,y;
    101     char ch;
    102 }data[MAXN];
    103 int f(int i,int j)//第几宫 
    104 {
    105     return ((i-1)/4)*4+(j+3)/4;
    106 }
    107 int main()
    108 {
    109     int test=0;
    110     while(~scanf("%s",str[1]+1))
    111     {
    112         for(int i=2;i<=16;++i) scanf("%s",str[i]+1);
    113         int cur=0,t;
    114         if(test) puts("");
    115         dlx.init(16*16*16,16*16*4);
    116         for(int i=1;i<=16;++i)
    117         {
    118             for(int j=1;j<=16;j++)
    119             {
    120                 if(str[i][j]=='-')
    121                 {
    122                     for(int t=1;t<=16;++t)
    123                     {
    124                         dlx.add(++cur,(i-1)*16+j);
    125                         dlx.add(cur,(i-1)*16+t+256);
    126                         dlx.add(cur,(j-1)*16+t+256*2);
    127                         dlx.add(cur,(f(i,j)-1)*16+t+256*3);
    128                         data[cur].x=i,data[cur].y=j,data[cur].ch=char('A'+t-1);
    129                     }
    130                 }
    131                 else
    132                 {
    133                     t=str[i][j]-'A'+1;
    134                     dlx.add(++cur,(i-1)*16+j);
    135                     dlx.add(cur,(i-1)*16+t+256);
    136                     dlx.add(cur,(j-1)*16+t+256*2);
    137                     dlx.add(cur,(f(i,j)-1)*16+t+256*3);
    138                     data[cur].x=i,data[cur].y=j,data[cur].ch=char('A'+t-1);
    139                 }
    140             }    
    141         } 
    142         /*cout<<dlx.dance(1)<<endl;
    143         cout<<dlx.g<<endl;*/
    144         if(!dlx.dance(1)) exit(-1);
    145         //cout<<dlx.g<<endl;
    146         for(int i=1;i<=256;++i)
    147         str[data[dlx.ans[i]].x][data[dlx.ans[i]].y]=data[dlx.ans[i]].ch;
    148         for(int i=1;i<=16;++i)
    149         {
    150             cout<<str[i]+1;
    151             cout<<"
    ";
    152         }
    153         test++;
    154     }
    155     
    156     
    157 }
    158 /*
    159 --A----C-----O-I
    160 -J--A-B-P-CGF-H-
    161 --D--F-I-E----P-
    162 -G-EL-H----M-J--
    163 ----E----C--G---
    164 -I--K-GA-B---E-J
    165 D-GP--J-F----A--
    166 -E---C-B--DP--O-
    167 E--F-M--D--L-K-A
    168 -C--------O-I-L-
    169 H-P-C--F-A--B---
    170 ---G-OD---J----H
    171 K---J----H-A-P-L
    172 --B--P--E--K--A-
    173 -H--B--K--FI-C--
    174 --F---C--D--H-N-
    175 */
    View Code

    H、Squiggly Sudoku

    9*9数独,不同的是每个小宫是给定的连续不规则的,需要预处理一下

      1 #include<iostream>
      2 #include<sstream>
      3 #include<fstream>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<iomanip>
      7 #include<cstdlib>
      8 #include<cctype>
      9 #include<vector>
     10 #include<string>
     11 #include<cmath>
     12 #include<ctime>
     13 #include<stack>
     14 #include<queue>
     15 #include<map>
     16 #include<set>
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define random(a,b) (rand()%(b-a+1)+a)
     19 #define ll long long
     20 #define ull unsigned long long
     21 #define e 2.71828182
     22 #define Pi acos(-1.0)
     23 #define ls(rt) (rt<<1)
     24 #define rs(rt) (rt<<1|1)
     25 #define lowbit(x) (x&(-x))
     26 using namespace std;
     27 const int MAXN=1e3;
     28 const int MAXM=4e2;
     29 const int MAX=4e5+5;
     30 int read()
     31 {
     32     int s=1,x=0;
     33     char ch=getchar();
     34     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
     35     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
     36     return x*s;
     37 }
     38 struct DLX
     39 {
     40     int n,m,cnt,g,mul;
     41     int U[MAX],D[MAX],R[MAX],L[MAX],row[MAX],col[MAX];
     42     int H[MAXN],S[MAXM],ans[MAXN],tmp[MAXN];
     43     void init(int _n,int _m)
     44     {
     45         n=_n,m=_m,g=0,mul=0;
     46         for(int i=0;i<=m;++i)
     47         S[i]=0,U[i]=D[i]=i,L[i]=i-1,R[i]=i+1;
     48         R[m]=0,L[0]=m,cnt=m;
     49         for(int i=1;i<=n;++i)
     50         H[i]=-1;
     51     }
     52     void add(int r,int c)
     53     {
     54         ++S[col[++cnt]=c];
     55         row[cnt]=r;
     56         D[cnt]=D[c],U[D[c]]=cnt;
     57         U[cnt]=c,D[c]=cnt;
     58         if(H[r]<0) H[r]=L[cnt]=R[cnt]=cnt;
     59         else R[cnt]=R[H[r]],L[R[H[r]]]=cnt,L[cnt]=H[r],R[H[r]]=cnt;
     60     }
     61     void remove(int c)
     62     {
     63         L[R[c]]=L[c],R[L[c]]=R[c];
     64         for(int i=D[c];i!=c;i=D[i])
     65         for(int j=R[i];j!=i;j=R[j])
     66         U[D[j]]=U[j],D[U[j]]=D[j],--S[col[j]];
     67     }
     68     void resume(int c)
     69     {
     70         for(int i=U[c];i!=c;i=U[i])
     71         for(int j=L[i];j!=i;j=L[j])
     72         ++S[col[U[D[j]]=D[U[j]]=j]];
     73         L[R[c]]=R[L[c]]=c;
     74     }
     75     void dance(int k)
     76     {  
     77         if(mul>=1) return;
     78         if(R[0]==0)
     79         {
     80             if(g==0) 
     81             {
     82                 g=k-1;
     83                 for(int d=1;d<=k-1;++d)
     84                 ans[d]=tmp[d];
     85             }
     86             else mul=1;
     87             return;
     88         }
     89         int c=R[0];
     90         for(int i=R[0];i!=0;i=R[i])
     91         if(S[i]<S[c]) c=i;
     92         remove(c);
     93         for(int i=D[c];i!=c;i=D[i])
     94         {
     95             for(int j=R[i];j!=i;j=R[j]) remove(col[j]);
     96             tmp[k]=row[i];
     97             dance(k+1);
     98             for(int j=L[i];j!=i;j=L[j]) resume(col[j]);
     99         }
    100         resume(c);
    101         return ;
    102     }
    103 }dlx;
    104 int G[10][10];
    105 int grid[10][10];
    106 int visit[10][10];
    107 int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
    108 int dir[4]={4,6,7,5};//1<<4, 1<<6, 1<<7, 1<<5 
    109 bool isin(int x,int y)
    110 {
    111     return (x>=1&&x<=9&&y>=1&&y<=9);
    112 }
    113 void dfs(int id,int x,int y)
    114 {
    115     visit[x][y]=1;
    116     grid[x][y]=id;
    117     for(int i=0;i<4;++i)//up, down, left, right
    118     {
    119         int xx=x+dx[i],yy=y+dy[i];
    120         if(G[x][y]&(1<<dir[i])) G[x][y]-=(1<<dir[i]);//if G[x][y] is border
    121         else if(isin(xx,yy)&&!visit[xx][yy]) dfs(id,xx,yy);
    122     }
    123 }
    124 struct node
    125 {
    126     int x,y,num;
    127 }data[MAXN];
    128 int main()
    129 {
    130     int test=read(),t;
    131     for(int w=1;w<=test;++w)
    132     {
    133         cout<<"Case "<<w<<":
    ";
    134         for(int i=1;i<=9;++i)
    135         for(int j=1;j<=9;++j)
    136         G[i][j]=read();        
    137             
    138         mem(visit,0);
    139         dlx.init(729,324);
    140         int cur=0;
    141         for(int i=1;i<=9;++i)
    142         for(int j=1;j<=9;++j)
    143         if(!visit[i][j])
    144         dfs(++cur,i,j);
    145         cur=0;
    146         for(int i=1;i<=9;++i)
    147         {
    148             for(int j=1;j<=9;++j)
    149             {
    150                 if(G[i][j])
    151                 {
    152                     t=G[i][j];
    153                     dlx.add(++cur,(i-1)*9+j);
    154                     dlx.add(cur,(i-1)*9+t+81);
    155                     dlx.add(cur,(j-1)*9+t+81*2);
    156                     dlx.add(cur,(grid[i][j]-1)*9+t+81*3);
    157                     data[cur].x=i,data[cur].y=j,data[cur].num=t;
    158                 }
    159                 else
    160                 {
    161                     for(t=1;t<=9;++t)
    162                     {
    163                         dlx.add(++cur,(i-1)*9+j);
    164                         dlx.add(cur,(i-1)*9+t+81);
    165                         dlx.add(cur,(j-1)*9+t+81*2);
    166                         dlx.add(cur,(grid[i][j]-1)*9+t+81*3);
    167                         data[cur].x=i,data[cur].y=j,data[cur].num=t;
    168                     }
    169                 }
    170             }
    171         }
    172         dlx.dance(1);
    173         if(dlx.g==0) puts("No solution");
    174         else if(dlx.mul==1) puts("Multiple Solutions");
    175         else
    176         {
    177             for(int i=1;i<=81;++i)
    178             G[data[dlx.ans[i]].x][data[dlx.ans[i]].y]=data[dlx.ans[i]].num;
    179             for(int i=1;i<=9;++i)
    180             {
    181                 for(int j=1;j<=9;++j)
    182                 cout<<G[i][j];
    183                 cout<<endl;
    184             }
    185         }
    186     } 
    187 }
    View Code

    I、Divisibility

     给定n个数,选出最多k个数,使得这k个数中两两互不整除。

    构造DLX求解重复覆盖问题,令第i行表示选第i个数,第i行j列为1表示第i个数与第j个数有整除关系,为0表示没有

    那么,就是求重复覆盖问题的最大解

    m
      1 #include<iostream>
      2 #include<sstream>
      3 #include<fstream>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<iomanip>
      7 #include<cstdlib>
      8 #include<cctype>
      9 #include<vector>
     10 #include<string>
     11 #include<cmath>
     12 #include<ctime>
     13 #include<stack>
     14 #include<queue>
     15 #include<map>
     16 #include<set>
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define random(a,b) (rand()%(b-a+1)+a)
     19 #define ll long long
     20 #define ull unsigned long long
     21 #define e 2.71828182
     22 #define Pi acos(-1.0)
     23 #define ls(rt) (rt<<1)
     24 #define rs(rt) (rt<<1|1)
     25 #define lowbit(x) (x&(-x))
     26 using namespace std;
     27 const int MAXN=1e3+5;
     28 const int MAXM=1e3+5;
     29 const int MAX=1e6+5; 
     30 ull a[MAXN];
     31 struct DLX
     32 {
     33     int n,m,cnt,g;
     34     int U[MAX],D[MAX],R[MAX],L[MAX],row[MAX],col[MAX];
     35     int H[MAXN],S[MAXM];
     36     bool v[MAX];
     37     void init(int _n,int _m)
     38     {
     39         n=_n,m=_m,g=-1;
     40         for(int i=0;i<=m;++i)
     41         S[i]=0,U[i]=D[i]=i,L[i]=i-1,R[i]=i+1;
     42         R[m]=0,L[0]=m,cnt=m;
     43         mem(H,-1);
     44     }
     45     void add(int r,int c)
     46     {
     47         ++S[col[++cnt]=c];
     48         row[cnt]=r;
     49         D[cnt]=D[c],U[D[c]]=cnt;
     50         U[cnt]=c,D[c]=cnt;
     51         if(H[r]<0) H[r]=L[cnt]=R[cnt]=cnt;
     52         else R[cnt]=R[H[r]],L[R[H[r]]]=cnt,L[cnt]=H[r],R[H[r]]=cnt;
     53     }
     54     void remove(int c)
     55     {
     56         for(int i=D[c];i!=c;i=D[i])
     57         L[R[i]]=L[i],R[L[i]]=R[i];
     58     }
     59     void resume(int c)
     60     {
     61         for(int i=U[c];i!=c;i=U[i])
     62         L[R[i]]=R[L[i]]=i;
     63     }
     64     int h()
     65     {
     66         int ret=0;
     67         for(int i=R[0];i!=0;i=R[i]) v[i]=true;
     68         for(int i=R[0];i!=0;i=R[i])
     69         {
     70             if(!v[i]) continue;
     71             ret++,v[i]=false;
     72             for(int j=D[i];j!=i;j=D[j])
     73             for(int k=R[j];k!=j;k=R[k])
     74             v[col[k]]=false;
     75         }    
     76         return ret;
     77     } 
     78     void dance(int d)
     79     {
     80         if(d+h()<=g) return;
     81         if(R[0]==0)
     82         {
     83             if(d>g) g=d;
     84             return;
     85         }
     86         int c=R[0];
     87         for(int i=R[0];i!=0;i=R[i])
     88         if(S[i]<S[c]) c=i;
     89         for(int i=D[c];i!=c;i=D[i])
     90         {
     91             remove(i);
     92             for(int j=R[i];j!=i;j=R[j]) remove(j);
     93             dance(d+1);
     94             for(int j=L[i];j!=i;j=L[j]) resume(j);
     95             resume(i);
     96         }
     97         return ;
     98     }
     99 }dlx;
    100 ull read()
    101 {
    102     ull s=1,x=0;
    103     char ch=getchar();
    104     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    105     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    106     return x*s;
    107 }
    108 int main()
    109 {
    110     ull test=read();
    111     while(test--)
    112     {
    113         ull n=read();
    114         dlx.init(n,n);
    115         for(int i=1;i<=n;++i) a[i]=read();
    116         for(int i=1;i<=n;++i)
    117         {
    118             for(int j=1;j<=n;++j)
    119             {
    120                 if(a[i]%a[j]==0||a[j]%a[i]==0)
    121                 dlx.add(i,j);
    122             }
    123         }
    124         dlx.dance(0);
    125         cout<<dlx.g<<endl;
    126     }
    127 }
    View Code

    J、A simple math problem

  • 相关阅读:
    使用VS Code插件Graphviz Preview来画图
    Y1S002 xshell脚本编写示意
    Y1S001 ubuntu下samba安装配置以及使用vbs映射到驱动器
    Y1吐槽002 情绪
    Y1E001 HDI二阶板、三阶板
    Y1O001波分复用器
    2018-4-5-cadence skill
    2018-4-5-MEMS
    2018-4-5-硬件集成测试规程结构
    Cadence学习笔记
  • 原文地址:https://www.cnblogs.com/wangzhebufangqi/p/11388385.html
Copyright © 2020-2023  润新知