欢迎来到就算过了一载春秋的博客

不管过了几载春秋,我还是会偶尔想起。

[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<<"\n";
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<<"\n";
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<<"\n";
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<<":\n";
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

 

posted on 2019-08-21 13:59  就算过了一载春秋  阅读(278)  评论(0)    收藏  举报

导航