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
此题已挂,模板题
注意坐标转换吧(TLE了一上午)。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
C、Radar
n座城,m个雷达站,最多安k个雷达,问安装雷达的最小半径使得n座城都在雷达范围内。
二分雷达的半径,判定最多k个雷达半径为r时能否覆盖到n座城,判定函数中用DLX求重复覆盖。
DLX中每一行代表一个雷达和n座城的覆盖关系。
注意精确覆盖和重复覆盖模板中有区别。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
D、神龙的难题
一次操作能将n1*m1的元素变为0,问将n*m的元素全部变为0(有一些原先就是0)最少的操作数。
将原来n*m的元素中为1的作为列,枚举每次操作的左上角作为行,重复覆盖的最小值。
注意剪枝!!!(有个地方不加等于就超时了)
注意MAXM、MAXN、MAX的定义!!不要开小了,不然会死循环?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
有时为了避免麻烦,可以添加空行进去
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
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数独,转化为精确覆盖问题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
G、Sudoku
16*16数独,同上
这题数据太坑,样例输入错了,还要注意有多组数据,每组的输出要多加一个换行
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 */
9*9数独,不同的是每个小宫是给定的连续不规则的,需要预处理一下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
给定n个数,选出最多k个数,使得这k个数中两两互不整除。
构造DLX求解重复覆盖问题,令第i行表示选第i个数,第i行j列为1表示第i个数与第j个数有整除关系,为0表示没有
那么,就是求重复覆盖问题的最大解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }