1. hust 1017 DLX精确覆盖 模板题

勉强写了注释,但还是一脸懵逼,感觉插入方式明显有问题但又不知道哪里不对而且好像能得出正确结果真是奇了怪了

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <map>
  6 #include <vector>
  7 #include <string>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <math.h>
 11
 12 #define SIGMA_SIZE 26
 13 #define lson rt<<1
 14 #define rson rt<<1|1
 15 #pragma warning ( disable : 4996 )
 16
 17 using namespace std;
 18 typedef long long LL;
 19 inline LL LMax(LL a,LL b)    { return a>b?a:b; }
 20 inline LL LMin(LL a,LL b)    { return a>b?b:a; }
 21 inline int Max(int a,int b) { return a>b?a:b; }
 22 inline int Min(int a,int b) { return a>b?b:a; }
 23 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
 24 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
 25 const LL INF = 0x3f3f3f3f3f3f3f3f;
 26 const LL mod  = 1000000007;
 27 const int inf  = 0x3f3f3f3f;
 28 const int maxk = 1e5+5;
 29 const int maxn = 1e4+5;
 30
 31
 32 //第一行为虚拟行,是人为加上的,一共有m+1个点(第一个点独立于整个矩阵)
 33 //而后加入的值为1的点标号用size表示
 34 //即第一行一共m+1个点,所以size先从0~m,之后每加入一个为1的点,size++
 35 //大部分数组X都用X[size]来标识标号为size的点的信息
 36 struct DLX {
 37     int n, m, size, fin;
 38     int U[maxn], D[maxn], L[maxn], R[maxn];//上下左右
 39     int head[maxn], S[maxn];                //分别存每一行第一个1的点的标号和每一列1的个数
 40     int row[maxn], col[maxn], ans[maxn];    //row,col表示第size个点在哪一行/列
 41
 42
 43     void init( int _n, int _m )
 44     {
 45         n = _n; m = _m;
 46         for ( int i = 0; i <= m; i++ )    //初始化第一行(人为增加的虚拟行)
 47         {
 48             S[i] = 0;
 49             U[i] = D[i] = i;
 50             L[i] = i-1;
 51             R[i] = i+1;
 52         }
 53         R[m] = 0; L[0] = m;        //第一行的最后一个元素指向第一个
 54         size = m;                //从m开始以后都是普通节点
 55         memset( head, -1, sizeof(head) );
 56         head[0] = 0;
 57     }
 58
 59     void link( int r, int c )
 60     {
 61         size++;                    //得到新的点标号
 62         col[size] = c;            //第size个点在第c列
 63         row[size] = r;            //第size个点在第r行
 64         S[c]++;                    //第c列1的个数+1
 65
 66         //组成一个环,和下面左右一样的插法
 67         D[size] = D[c];
 68         U[size] = c;
 69         U[D[c]] = size;
 70         D[c] = size;
 71
 72         //如果该行没有为1的节点
 73         if ( head[r] < 0 ) head[r] = L[size] = R[size] = size;
 74         else
 75         {
 76             //组成一个环,插在head[r]和head[r]右边那个元素中间
 77             R[size] = R[head[r]];
 78             L[R[size]] = size;
 79             L[size] = head[r];
 80             R[head[r]] = size;
 81         }
 82     }
 83
 84     void remove( int c )   //删除列c及其所在行
 85     {
 86         L[R[c]] = L[c]; R[L[c]] = R[c];                //c的左右两个节点互相连接
 87         for ( int i = D[c]; i != c; i = D[i] )        //屏蔽c列
 88             for ( int j = R[i]; j != i; j = R[j] )
 89             {
 90                 U[D[j]] = U[j];
 91                 D[U[j]] = D[j];
 92                 --S[col[j]];        //j所在的列的1的数目数减少
 93             }
 94     }
 95
 96     void resume( int c )
 97     {
 98         for ( int i = U[c]; i != c; i = U[i] )
 99             for ( int j = L[i]; j != i; j = L[j] )
100             {
101                 U[D[j]] = D[U[j]] = j;
102                 ++S[col[j]];
103             }
104         L[R[c]] = R[L[c]] = c;
105     }
106
107     bool dance( int d )
108     {
109         if ( R[0] == 0 ) //第0行没有节点
110         {
111             fin = d;
112             return true;
113         }
114
115         //找出含1数目最小的一列
116         int mark = R[0];
117         for ( int i = R[0]; i != 0; i = R[i] )
118             if ( S[i] < S[mark] )
119                 mark = i;
120
121         remove(mark);    //移除列mark的1的对应行
122         for ( int i = D[mark]; i != mark; i = D[i] )
123         {
124             ans[d] = row[i];
125             //移除该行的1的对应列
126             for ( int j = R[i]; j != i; j = R[j] )
127                 remove(col[j]);
128
129             if ( dance(d+1) )
130                 return true;
131
132             //倒着恢复
133             for ( int j = L[i]; j != i; j = L[j] )
134                 resume(col[j]);
135         }
136         resume(mark);
137         return false;
138     }
139 }dlx;
140
141
142 int main()
143 {
144     //freopen("F:\\cpp\\test.txt","r",stdin);
145
146     int n, m;
147     while ( ~scanf("%d %d", &n, &m) )
148     {
149         dlx.init(n,m);
150         for ( int i = 1; i <= n; i++ )
151         {
152             int num, j;
153             scanf("%d",&num);
154             while (num--)
155             {
156                 scanf("%d",&j);
157                 dlx.link(i,j);
158             }
159         }
160
161         if ( dlx.dance(0) )
162         {
163             printf( "%d", dlx.fin );
164             for ( int i = 0; i < dlx.fin; i++ )
165                 printf( " %d", dlx.ans[i] );
166             printf( "\n" );
167             //continue;
168         }
169         else
170             printf("NO\n");
171     }
172
173     return 0;
174 }

View Code

  2. ZOJ 3209 矩阵映射DLX精确覆盖

  给一个大矩阵和p个小矩阵,问在p个小矩阵中能否取若干个使它们覆盖整个大矩阵,并且小矩阵间两两互不覆盖。

把大矩阵分为1-n*m个小块(就是横竖切割n和m次),则题目的要求就变成了每个小块都要被一个且仅能有一个小矩阵覆盖,然后就是映射了,因为每个小矩阵能覆盖1~n*m这么多编号小块中的某些块,那么我们让每个小矩阵为1行,并设n*m列,则题目就变成p行n*m列的矩阵对其求精确覆盖了

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <map>
  6 #include <vector>
  7 #include <string>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <math.h>
 11
 12 #define SIGMA_SIZE 26
 13 #define lson rt<<1
 14 #define rson rt<<1|1
 15 #pragma warning ( disable : 4996 )
 16
 17 using namespace std;
 18 typedef long long LL;
 19 inline LL LMax(LL a,LL b)      { return a>b?a:b; }
 20 inline LL LMin(LL a,LL b)      { return a>b?b:a; }
 21 inline int Max(int a,int b)    { return a>b?a:b; }
 22 inline int Min(int a,int b)       { return a>b?b:a; }
 23 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
 24 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
 25 const LL INF = 0x3f3f3f3f3f3f3f3f;
 26 const LL mod  = 1000000007;
 27 const int inf  = 0x3f3f3f3f;
 28 const int maxk = 1e5+5;
 29 const int maxn = 1e5;
 30
 31 struct DLX {
 32     int n, m, size, fin;
 33     int U[maxn], D[maxn], L[maxn], R[maxn]; //上下左右
 34     int head[maxn], S[maxn];                //分别存每一行第一个1的点的标号和每一列1的个数
 35     int row[maxn], col[maxn], ans[maxn];    //row,col表示第size个点在哪一行/列
 36
 37
 38     void init( int _n, int _m )
 39     {
 40         n = _n; m = _m;
 41         for ( int i = 0; i <= m; i++ )    //初始化第一行(人为增加的虚拟行)
 42         {
 43             S[i] = 0;
 44             U[i] = D[i] = i;
 45             L[i] = i-1;
 46             R[i] = i+1;
 47         }
 48         R[m] = 0; L[0] = m;        //第一行的最后一个元素指向第一个
 49         fin = -1; size = m;                //从m开始以后都是普通节点
 50         memset( head, -1, sizeof(head) );
 51     }
 52
 53     void link( int r, int c )
 54     {
 55         size++;                    //得到新的点标号
 56         col[size] = c;            //第size个点在第c列
 57         row[size] = r;            //第size个点在第r行
 58         S[c]++;                    //第c列1的个数+1
 59
 60         //组成一个环,和下面左右一样的插法
 61         D[size] = D[c];
 62         U[size] = c;
 63         U[D[c]] = size;
 64         D[c] = size;
 65
 66         //如果该行没有为1的节点
 67         if ( head[r] < 0 ) head[r] = L[size] = R[size] = size;
 68         else
 69         {
 70             //组成一个环,插在head[r]和head[r]右边那个元素中间
 71             R[size] = R[head[r]];
 72             L[R[size]] = size;
 73             L[size] = head[r];
 74             R[head[r]] = size;
 75         }
 76     }
 77
 78     void remove( int c )   //删除列c及其所在行
 79     {
 80         L[R[c]] = L[c]; R[L[c]] = R[c];                //c的左右两个节点互相连接
 81         for ( int i = D[c]; i != c; i = D[i] )        //屏蔽c列
 82             for ( int j = R[i]; j != i; j = R[j] )
 83             {
 84                 U[D[j]] = U[j];
 85                 D[U[j]] = D[j];
 86                 --S[col[j]];        //j所在的列的1的数目数减少
 87             }
 88     }
 89
 90     void resume( int c )
 91     {
 92         for ( int i = U[c]; i != c; i = U[i] )
 93             for ( int j = L[i]; j != i; j = L[j] )
 94             {
 95                 U[D[j]] = D[U[j]] = j;
 96                 ++S[col[j]];
 97             }
 98         L[R[c]] = R[L[c]] = c;
 99     }
100
101     void dance( int d )
102     {
103         if ( fin != -1 && fin <= d )
104             return;
105         if ( R[0] == 0 ) //第0行没有节点
106         {
107             fin = d;
108             return;
109         }
110
111         //找出含1数目最小的一列
112         int mark = R[0];
113         for ( int i = R[0]; i != 0; i = R[i] )
114             if ( S[i] < S[mark] )
115                 mark = i;
116
117         remove(mark);    //移除列mark的1的对应行
118         for ( int i = D[mark]; i != mark; i = D[i] )
119         {
120             ans[d] = row[i];
121             //移除该行的1的对应列
122             for ( int j = R[i]; j != i; j = R[j] )
123                 remove(col[j]);
124
125             dance(d+1);
126
127             //倒着恢复
128             for ( int j = L[i]; j != i; j = L[j] )
129                 resume(col[j]);
130         }
131         resume(mark);
132
133         return;
134     }
135 }dlx;
136
137
138 int pos[32][32];
139
140 int main()
141 {
142     freopen("F:\\cpp\\test.txt","r",stdin);
143
144     int n, m, p;
145     int x1, x2, y1, y2;
146     int T; cin >> T;
147     while (T--)
148     {
149         scanf("%d %d %d", &n, &m, &p);
150         dlx.init(p, n*m);
151
152         int id = 1;
153         for ( int i = 1; i <= n; i++ )
154             for ( int j = 1; j <= m; j++ )
155                 pos[i][j] = id++;
156
157         for ( int r = 1; r <= p; r++ )
158         {
159             scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
160             //注意对应的规则
161             for ( int i = x1+1; i <= x2; i++ )
162                 for ( int j = y1+1; j <= y2; j++ )
163                     dlx.link( r, pos[i][j] );
164         }
165
166         dlx.dance(0);
167         printf("%d\n", dlx.fin);
168     }
169
170     return 0;
171 }

View Code

懒得修改了...直接贴另一种返回

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <map>
  6 #include <vector>
  7 #include <string>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <math.h>
 11
 12 #define SIGMA_SIZE 26
 13 #define lson rt<<1
 14 #define rson rt<<1|1
 15 #pragma warning ( disable : 4996 )
 16
 17 using namespace std;
 18 typedef long long LL;
 19 inline LL LMax(LL a,LL b)      { return a>b?a:b; }
 20 inline LL LMin(LL a,LL b)      { return a>b?b:a; }
 21 inline int Max(int a,int b)    { return a>b?a:b; }
 22 inline int Min(int a,int b)       { return a>b?b:a; }
 23 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
 24 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
 25 const LL INF = 0x3f3f3f3f3f3f3f3f;
 26 const LL mod  = 1000000007;
 27 const int inf  = 0x3f3f3f3f;
 28 const int maxk = 1e5+5;
 29 const int maxn = 1e5;
 30
 31 struct DLX {
 32     int n, m, size, fin;
 33     int U[maxn], D[maxn], L[maxn], R[maxn]; //上下左右
 34     int head[maxn], S[maxn];                //分别存每一行第一个1的点的标号和每一列1的个数
 35     int row[maxn], col[maxn], ans[maxn];    //row,col表示第size个点在哪一行/列
 36
 37
 38     void init( int _n, int _m )
 39     {
 40         n = _n; m = _m;
 41         for ( int i = 0; i <= m; i++ )    //初始化第一行(人为增加的虚拟行)
 42         {
 43             S[i] = 0;
 44             U[i] = D[i] = i;
 45             L[i] = i-1;
 46             R[i] = i+1;
 47         }
 48         R[m] = 0; L[0] = m;        //第一行的最后一个元素指向第一个
 49         fin = -1; size = m;                //从m开始以后都是普通节点
 50         memset( head, -1, sizeof(head) );
 51     }
 52
 53     void link( int r, int c )
 54     {
 55         size++;                    //得到新的点标号
 56         col[size] = c;            //第size个点在第c列
 57         row[size] = r;            //第size个点在第r行
 58         S[c]++;                    //第c列1的个数+1
 59
 60         //组成一个环,和下面左右一样的插法
 61         D[size] = D[c];
 62         U[size] = c;
 63         U[D[c]] = size;
 64         D[c] = size;
 65
 66         //如果该行没有为1的节点
 67         if ( head[r] < 0 ) head[r] = L[size] = R[size] = size;
 68         else
 69         {
 70             //组成一个环,插在head[r]和head[r]右边那个元素中间
 71             R[size] = R[head[r]];
 72             L[R[size]] = size;
 73             L[size] = head[r];
 74             R[head[r]] = size;
 75         }
 76     }
 77
 78     void remove( int c )   //删除列c及其所在行
 79     {
 80         L[R[c]] = L[c]; R[L[c]] = R[c];                //c的左右两个节点互相连接
 81         for ( int i = D[c]; i != c; i = D[i] )        //屏蔽c列
 82             for ( int j = R[i]; j != i; j = R[j] )
 83             {
 84                 U[D[j]] = U[j];
 85                 D[U[j]] = D[j];
 86                 --S[col[j]];        //j所在的列的1的数目数减少
 87             }
 88     }
 89
 90     void resume( int c )
 91     {
 92         for ( int i = U[c]; i != c; i = U[i] )
 93             for ( int j = L[i]; j != i; j = L[j] )
 94             {
 95                 U[D[j]] = D[U[j]] = j;
 96                 ++S[col[j]];
 97             }
 98         L[R[c]] = R[L[c]] = c;
 99     }
100
101     bool dance( int d )
102     {
103         if ( fin != -1 && fin <= d )
104             return false;
105         if ( R[0] == 0 ) //第0行没有节点
106         {
107             fin = d;
108             return true;
109         }
110
111         //找出含1数目最小的一列
112         int mark = R[0];
113         for ( int i = R[0]; i != 0; i = R[i] )
114             if ( S[i] < S[mark] )
115                 mark = i;
116
117         remove(mark);    //移除列mark的1的对应行
118         for ( int i = D[mark]; i != mark; i = D[i] )
119         {
120             ans[d] = row[i];
121             //移除该行的1的对应列
122             for ( int j = R[i]; j != i; j = R[j] )
123                 remove(col[j]);
124
125             dance(d+1);
126
127             //倒着恢复
128             for ( int j = L[i]; j != i; j = L[j] )
129                 resume(col[j]);
130         }
131         resume(mark);
132
133         return false;
134     }
135 }dlx;
136
137
138 int pos[32][32];
139
140 int main()
141 {
142     freopen("F:\\cpp\\test.txt","r",stdin);
143
144     int n, m, p;
145     int x1, x2, y1, y2;
146     int T; cin >> T;
147     while (T--)
148     {
149         scanf("%d %d %d", &n, &m, &p);
150         dlx.init(p, n*m);
151
152         int id = 1;
153         for ( int i = 1; i <= n; i++ )
154             for ( int j = 1; j <= m; j++ )
155                 pos[i][j] = id++;
156
157         for ( int r = 1; r <= p; r++ )
158         {
159             scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
160             //注意对应的规则
161             for ( int i = x1+1; i <= x2; i++ )
162                 for ( int j = y1+1; j <= y2; j++ )
163                     dlx.link( r, pos[i][j] );
164         }
165
166         dlx.dance(0);
167         printf("%d\n", dlx.fin);
168     }
169
170     return 0;
171 }

View Code

  3.HDU 2295 圆形重复覆盖+二分

  一脸懵逼逼逼....如果说之前那个模板还勉强看的懂...这个就完全懵逼了(还非常容易写错)。题目比较简单就不说了

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <map>
  6 #include <vector>
  7 #include <string>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <math.h>
 11
 12 #define SIGMA_SIZE 26
 13 #define lson rt<<1
 14 #define rson rt<<1|1
 15 #pragma warning ( disable : 4996 )
 16
 17 using namespace std;
 18 typedef long long LL;
 19 inline LL LMax(LL a,LL b)      { return a>b?a:b; }
 20 inline LL LMin(LL a,LL b)      { return a>b?b:a; }
 21 inline int Max(int a,int b)    { return a>b?a:b; }
 22 inline int Min(int a,int b)       { return a>b?b:a; }
 23 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
 24 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
 25 const LL INF = 0x3f3f3f3f3f3f3f3f;
 26 const LL mod  = 1000000007;
 27 const double eps = 1e-8;
 28 const int inf  = 0x3f3f3f3f;
 29 const int maxk = 1e4;
 30 const int maxn = 105;
 31
 32 struct DLX {
 33     int n, m, size, fin;
 34     int U[maxk], D[maxk], L[maxk], R[maxk];
 35     int C[maxk];
 36
 37     int head[maxk];
 38     int S[maxk];
 39     bool vis[maxk];
 40
 41     void init( int _n, int _m )
 42     {
 43         n = _n; m = _m;
 44         for ( int i = 0; i <= m; i++ )
 45         {
 46             U[i] = D[i] = i;
 47             L[i] = i-1;
 48             R[i] = i+1;
 49             S[i] = 0;
 50         }
 51         L[0] = m; R[m] = 0;
 52         size = m;
 53         memset( head, -1, sizeof(head) );
 54     }
 55
 56     void link( int r, int c )
 57     {
 58         size++;
 59         C[size] = c;
 60         S[c]++;
 61
 62         D[size] = D[c];
 63         U[size] = c;
 64         U[D[c]] = size;
 65         D[c] = size;
 66
 67         if ( head[r] < 0 )
 68             head[r] = L[size] = R[size] = size;
 69         else
 70         {
 71             R[size] = R[head[r]];
 72             L[R[size]] = size;
 73             L[size] = head[r];
 74             R[head[r]] = size;
 75         }
 76     }
 77
 78     void remove( int id )
 79     {
 80         for ( int i = D[id]; i != id; i = D[i] )
 81         {
 82             L[R[i]] = L[i];
 83             R[L[i]] = R[i];
 84         }
 85     }
 86
 87     void resume( int id )
 88     {
 89         for ( int i = D[id]; i != id; i = D[i] )
 90             L[R[i]] = R[L[i]] = i;
 91     }
 92
 93     int h()
 94     {
 95         int sum = 0;
 96         memset( vis, 0, sizeof(vis) );
 97         for ( int i = R[0]; i != 0; i = R[i] )
 98             if (!vis[i])
 99             {
100                 sum++;
101                 for ( int j = D[i]; j != i; j = D[j] )
102                     for ( int k = R[j]; k != j; k = R[k] )
103                         vis[C[k]] = 1;
104             }
105         return sum;
106     }
107
108     void dance( int k )
109     {
110         int mark, mmin = inf;
111         if ( k + h() >= fin )
112             return;
113         if ( R[0] == 0 )
114         {
115             if ( k < fin )
116                 fin = k;
117             return;
118         }
119
120         for ( int i = R[0]; i != 0; i = R[i] )
121             if ( mmin > S[i] )
122             {
123                 mmin = S[i];
124                 mark = i;
125             }
126
127         for ( int i = D[mark]; i != mark; i = D[i] )
128         {
129             remove(i);
130             for ( int j = R[i]; j != i; j = R[j] ) remove(j);
131             dance(k+1);
132             for ( int j = R[i]; j != i; j = R[j] ) resume(j);
133             resume(i);
134         }
135     }
136 }dlx;
137
138 double mmap[maxn][2];
139 double cir[maxn][2];
140
141 void init( int n, int m )
142 {
143     for ( int i = 1; i <= n; i++ )
144         scanf("%lf %lf", &mmap[i][0], &mmap[i][1]);
145     for ( int i = 1; i <= m; i++ )
146         scanf("%lf %lf", &cir[i][0], &cir[i][1]);
147 }
148
149 double getdis( int i, int j )
150 {
151     double a = mmap[i][0] - cir[j][0];
152     double b = mmap[i][1] - cir[j][1];
153     a *= a; b *= b;
154     return sqrt(a+b);
155 }
156
157 bool judge( int n, int m, int k, double r )
158 {
159     dlx.init(m, n); dlx.fin = inf;
160
161     for ( int i = 1; i <= n; i++ )
162         for ( int j = 1; j <= m; j++ )
163         {
164             if ( r >= getdis(i,j) )
165                 dlx.link(j,i);
166         }
167     dlx.dance(0);
168     if ( dlx.fin <= k ) return 1;
169     else return 0;
170 }
171
172 int main()
173 {
174 #ifdef local
175     freopen("F:\\cpp\\test.txt","r",stdin);
176 #endif
177
178     int n, m, k;
179     int T; cin >> T;
180     while (T--)
181     {
182         scanf("%d %d %d", &n, &m, &k);
183         init(n,m);
184
185         double mid, lhs = 0.0, rhs = 1000.0;
186         while ( rhs - lhs > eps )
187         {
188             mid = (lhs+rhs) / 2;
189             if ( judge(n,m,k,mid) )
190                 rhs = mid;
191             else
192                 lhs = mid;
193         }
194         printf("%.6lf\n", (lhs+rhs)/2);
195     }
196     return 0;
197 }

View Code

  4.FZU 1686 矩形重复覆盖

  原来DLX主要是考察建模啊,模板实在不想每次都打一遍了...直接ctrl+c

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <map>
  6 #include <vector>
  7 #include <string>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <math.h>
 11
 12 #define SIGMA_SIZE 26
 13 #define lson rt<<1
 14 #define rson rt<<1|1
 15 #pragma warning ( disable : 4996 )
 16
 17 using namespace std;
 18 typedef long long LL;
 19 inline LL LMax(LL a,LL b)      { return a>b?a:b; }
 20 inline LL LMin(LL a,LL b)      { return a>b?b:a; }
 21 inline int Max(int a,int b)    { return a>b?a:b; }
 22 inline int Min(int a,int b)       { return a>b?b:a; }
 23 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
 24 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
 25 const LL INF = 0x3f3f3f3f3f3f3f3f;
 26 const LL mod  = 1000000007;
 27 const double eps = 1e-8;
 28 const int inf  = 0x3f3f3f3f;
 29 const int maxk = 1000;
 30 const int maxn = 105;
 31
 32 struct DLX {
 33     int n, m, size, fin;
 34     int U[maxk], D[maxk], L[maxk], R[maxk];
 35     int C[maxk];
 36
 37     int head[maxk];
 38     int S[maxk];
 39     bool vis[maxk];
 40
 41     void init( int _n, int _m )
 42     {
 43         n = _n; m = _m;
 44         for ( int i = 0; i <= m; i++ )
 45         {
 46             U[i] = D[i] = i;
 47             L[i] = i-1;
 48             R[i] = i+1;
 49             S[i] = 0;
 50         }
 51         L[0] = m; R[m] = 0;
 52         fin = inf; size = m;
 53         memset( head, -1, sizeof(head) );
 54     }
 55
 56     void link( int r, int c )
 57     {
 58         size++;
 59         C[size] = c;
 60         S[c]++;
 61
 62         D[size] = D[c];
 63         U[size] = c;
 64         U[D[c]] = size;
 65         D[c] = size;
 66
 67         if ( head[r] < 0 )
 68             head[r] = L[size] = R[size] = size;
 69         else
 70         {
 71             R[size] = R[head[r]];
 72             L[R[size]] = size;
 73             L[size] = head[r];
 74             R[head[r]] = size;
 75         }
 76     }
 77
 78     void remove( int id )
 79     {
 80         for ( int i = D[id]; i != id; i = D[i] )
 81         {
 82             L[R[i]] = L[i];
 83             R[L[i]] = R[i];
 84         }
 85     }
 86
 87     void resume( int id )
 88     {
 89         for ( int i = D[id]; i != id; i = D[i] )
 90             L[R[i]] = R[L[i]] = i;
 91     }
 92
 93     int h()
 94     {
 95         int sum = 0;
 96         memset( vis, 0, sizeof(vis) );
 97         for ( int i = R[0]; i != 0; i = R[i] )
 98             if (!vis[i])
 99             {
100                 sum++;
101                 for ( int j = D[i]; j != i; j = D[j] )
102                     for ( int k = R[j]; k != j; k = R[k] )
103                         vis[C[k]] = 1;
104             }
105         return sum;
106     }
107
108     void dance( int k )
109     {
110         int mark, mmin = inf;
111         if ( k + h() >= fin )
112             return;
113         if ( R[0] == 0 )
114         {
115             if ( k < fin )
116                 fin = k;
117             return;
118         }
119
120         for ( int i = R[0]; i != 0; i = R[i] )
121             if ( mmin > S[i] )
122             {
123                 mmin = S[i];
124                 mark = i;
125             }
126
127         for ( int i = D[mark]; i != mark; i = D[i] )
128         {
129             remove(i);
130             for ( int j = R[i]; j != i; j = R[j] ) remove(j);
131             dance(k+1);
132             for ( int j = R[i]; j != i; j = R[j] ) resume(j);
133             resume(i);
134         }
135     }
136 }dlx;
137
138 int mmap[20][20], g[20][20];
139
140 void init()
141 {
142     memset( mmap, 0, sizeof(mmap) );
143     memset( g, 0, sizeof(g) );
144 }
145
146 int main()
147 {
148 #ifdef local
149     freopen("F:\\cpp\\test.txt","r",stdin);
150 #endif
151
152     int R, C, r, c;
153     while ( ~scanf("%d %d", &R, &C) )
154     {
155         init();
156         int cnt = 0;
157         for ( int i = 1; i <= R; i++ )
158             for (int j = 1; j <= C; j++)
159             {
160                 scanf("%d", &mmap[i][j]);
161                 if ( mmap[i][j] )
162                     g[i][j] = ++cnt;
163             }
164         scanf("%d %d", &r, &c);
165         dlx.init( (R-r+1)*(C-c+1), cnt );
166
167         cnt = 1;
168         for ( int i = 1; i+r-1 <= R; i++ )
169             for ( int j = 1; j+c-1 <= C; j++ )
170             {
171                 for ( int a = i; a <= i+r-1; a++ )
172                     for ( int b = j; b <= j + c - 1; b++ )
173                         if (g[a][b])
174                             dlx.link(cnt, g[a][b]);
175                 cnt++;
176             }
177         dlx.dance(0);
178         printf("%d\n", dlx.fin);
179     }
180
181     return 0;
182 }

View Code

  5.POJ 3074

  求解数独....emmmm我得好好理解下才行

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <map>
  6 #include <vector>
  7 #include <string>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <math.h>
 11 #include <time.h>
 12
 13 #define SIGMA_SIZE 26
 14 #define lson rt<<1
 15 #define rson rt<<1|1
 16 #pragma warning ( disable : 4996 )
 17
 18 using namespace std;
 19 typedef long long LL;
 20 inline LL LMax(LL a,LL b)      { return a>b?a:b; }
 21 inline LL LMin(LL a,LL b)      { return a>b?b:a; }
 22 inline int Max(int a,int b)    { return a>b?a:b; }
 23 inline int Min(int a,int b)       { return a>b?b:a; }
 24 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
 25 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
 26 const LL INF = 0x3f3f3f3f3f3f3f3f;
 27 const LL mod  = 1000000007;
 28 const double eps = 1e-8;
 29 const int inf  = 0x3f3f3f3f;
 30 const int maxk = 1e8;
 31 const int maxn = 5000;
 32
 33 struct node {
 34     int x, y, k;
 35 }e[800];
 36
 37 struct DLX {
 38     int n, m, size, fin;
 39     int U[maxn], D[maxn], L[maxn], R[maxn];//上下左右
 40     int head[maxn], S[maxn];                //分别存每一行第一个1的点的标号和每一列1的个数
 41     int row[maxn], col[maxn], ans[maxn];    //row,col表示第size个点在哪一行/列
 42
 43
 44     void init( int _n, int _m )
 45     {
 46         n = _n; m = _m;
 47         for ( int i = 0; i <= m; i++ )    //初始化第一行(人为增加的虚拟行)
 48         {
 49             S[i] = 0;
 50             U[i] = D[i] = i;
 51             L[i] = i-1;
 52             R[i] = i+1;
 53         }
 54         R[m] = 0; L[0] = m;        //第一行的最后一个元素指向第一个
 55         size = m;                //从m开始以后都是普通节点
 56         memset( head, -1, sizeof(head) );
 57         head[0] = 0;
 58     }
 59
 60     void link( int r, int c )
 61     {
 62         size++;                    //得到新的点标号
 63         col[size] = c;            //第size个点在第c列
 64         row[size] = r;            //第size个点在第r行
 65         S[c]++;                    //第c列1的个数+1
 66
 67                                    //组成一个环,和下面左右一样的插法
 68         D[size] = D[c];
 69         U[size] = c;
 70         U[D[c]] = size;
 71         D[c] = size;
 72
 73         //如果该行没有为1的节点
 74         if ( head[r] < 0 ) head[r] = L[size] = R[size] = size;
 75         else
 76         {
 77             //组成一个环,插在head[r]和head[r]右边那个元素中间
 78             R[size] = R[head[r]];
 79             L[R[size]] = size;
 80             L[size] = head[r];
 81             R[head[r]] = size;
 82         }
 83     }
 84
 85     void remove( int c )   //删除列c及其所在行
 86     {
 87         L[R[c]] = L[c]; R[L[c]] = R[c];                //c的左右两个节点互相连接
 88         for ( int i = D[c]; i != c; i = D[i] )        //屏蔽c列
 89             for ( int j = R[i]; j != i; j = R[j] )
 90             {
 91                 U[D[j]] = U[j];
 92                 D[U[j]] = D[j];
 93                 --S[col[j]];        //j所在的列的1的数目数减少
 94             }
 95     }
 96
 97     void resume( int c )
 98     {
 99         for ( int i = U[c]; i != c; i = U[i] )
100             for ( int j = L[i]; j != i; j = L[j] )
101             {
102                 U[D[j]] = D[U[j]] = j;
103                 ++S[col[j]];
104             }
105         L[R[c]] = R[L[c]] = c;
106     }
107
108     bool dance( int d )
109     {
110         if ( R[0] == 0 ) //第0行没有节点
111         {
112             fin = d;
113             return true;
114         }
115
116         //找出含1数目最小的一列
117         int mark = R[0];
118         for ( int i = R[0]; i != 0; i = R[i] )
119             if ( S[i] < S[mark] )
120                 mark = i;
121
122         remove(mark);    //移除列mark的1的对应行
123         for ( int i = D[mark]; i != mark; i = D[i] )
124         {
125             ans[d] = row[i];
126             //移除该行的1的对应列
127             for ( int j = R[i]; j != i; j = R[j] )
128                 remove(col[j]);
129
130             if ( dance(d+1) )
131                 return true;
132
133             //倒着恢复
134             for ( int j = L[i]; j != i; j = L[j] )
135                 resume(col[j]);
136         }
137         resume(mark);
138         return false;
139     }
140 }dlx;
141
142
143 int mmap[10][10];
144 char sudoku[90];
145
146 void read()
147 {
148     dlx.init(750,324);
149     int row = 0;
150
151     for ( int i = 1; i <= 9; i++ )
152         for ( int j = 1; j <= 9; j++ )
153         {
154             if ( !mmap[i][j] )
155             {
156                 for ( int k = 1; k <= 9; k++ )
157                 {
158                     ++row;
159                     dlx.link(row, (i-1)*9+j);
160                     dlx.link(row, 81+(i-1)*9+k);
161                     dlx.link(row, 162+(j-1)*9+k);
162                     dlx.link(row,243+(((i-1)/3)*3+(j+2)/3-1)*9+k);
163                     e[row].x = i; e[row].y = j; e[row].k = k;
164                 }
165             }
166             else
167             {
168                 ++row;
169                 int k = mmap[i][j];
170                 dlx.link(row, (i-1)*9+j);
171                 dlx.link(row, 81+(i-1)*9+k);
172                 dlx.link(row, 162+(j-1)*9+k);
173                 dlx.link(row, 243+(((i-1)/3)*3+(j+2)/3-1)*9+k);
174                 e[row].x = i; e[row].y = j; e[row].k = k;
175             }
176         }
177
178 }
179
180 void init()
181 {
182     int t = 0;
183
184     for ( int i = 1; i <= 9; i++ )
185         for ( int j = 1; j <= 9; j++ )
186         {
187             if ( sudoku[++t] != '.' )
188                 mmap[i][j] = sudoku[t] - '0';
189             else
190                 mmap[i][j] = 0;
191         }
192
193     read();
194 }
195
196 int main()
197 {
198     //freopen("F:\\cpp\\test.txt", "r", stdin );
199
200     while ( ~scanf("%s", sudoku+1) )
201     {
202         if (sudoku[1] == 'e') break;
203         init();
204
205         dlx.dance(0);
206         for ( int i = 0; i < dlx.fin; i++ )
207         {
208             int tmp = dlx.ans[i];
209             sudoku[(e[tmp].x-1)*9 + e[tmp].y-1] = '0'+e[tmp].k;
210         }
211         sudoku[dlx.fin] = '\0';
212         printf("%s\n", sudoku);
213     }
214
215     return 0;
216 }

View Code

  6. HDU 5046

  和hdu2295基本一样,有个可以优化的方法是将可行的距离排序后二分下标,如果不这样做直接二分,左右区间要到1~4e9才行,而且大概率TLE(交了一发1300ms)

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <map>
  6 #include <vector>
  7 #include <string>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <math.h>
 11 #include <time.h>
 12
 13 #define SIGMA_SIZE 26
 14 #define lson rt<<1
 15 #define rson rt<<1|1
 16 #pragma warning ( disable : 4996 )
 17
 18 using namespace std;
 19 typedef long long LL;
 20 inline LL LMax(LL a,LL b)      { return a>b?a:b; }
 21 inline LL LMin(LL a,LL b)      { return a>b?b:a; }
 22 inline int Max(int a,int b)    { return a>b?a:b; }
 23 inline int Min(int a,int b)       { return a>b?b:a; }
 24 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
 25 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
 26 const LL INF = 0x3f3f3f3f3f3f3f3f;
 27 const LL mod  = 1000000007;
 28 const double eps = 1e-8;
 29 const int inf  = 0x3f3f3f3f;
 30 const int maxk = 5000;
 31 const int maxn = 5000;
 32
 33 int N, K;
 34
 35 struct DLX {
 36     int n, m, size, fin;
 37     int U[maxk], D[maxk], L[maxk], R[maxk];
 38     int C[maxk];
 39
 40     int head[65];
 41     int S[65];
 42     bool vis[maxk];
 43
 44     void init( int _n, int _m )
 45     {
 46         n = _n; m = _m;
 47         for ( int i = 0; i <= m; i++ )
 48         {
 49             U[i] = D[i] = i;
 50             L[i] = i-1;
 51             R[i] = i+1;
 52             S[i] = 0;
 53         }
 54         L[0] = m; R[m] = 0;
 55         size = m;
 56         memset( head, -1, sizeof(head) );
 57     }
 58
 59     void link( int r, int c )
 60     {
 61         size++;
 62         C[size] = c;
 63         S[c]++;
 64
 65         D[size] = D[c];
 66         U[size] = c;
 67         U[D[c]] = size;
 68         D[c] = size;
 69
 70         if ( head[r] < 0 )
 71             head[r] = L[size] = R[size] = size;
 72         else
 73         {
 74             R[size] = R[head[r]];
 75             L[R[size]] = size;
 76             L[size] = head[r];
 77             R[head[r]] = size;
 78         }
 79     }
 80
 81     void remove( int id )
 82     {
 83         for ( int i = D[id]; i != id; i = D[i] )
 84         {
 85             L[R[i]] = L[i];
 86             R[L[i]] = R[i];
 87         }
 88     }
 89
 90     void resume( int id )
 91     {
 92         for ( int i = D[id]; i != id; i = D[i] )
 93             L[R[i]] = R[L[i]] = i;
 94     }
 95
 96     int h()
 97     {
 98         int sum = 0;
 99         memset( vis, 0, sizeof(vis) );
100         for ( int i = R[0]; i != 0; i = R[i] )
101             if (!vis[i])
102             {
103                 sum++;
104                 for ( int j = D[i]; j != i; j = D[j] )
105                     for ( int k = R[j]; k != j; k = R[k] )
106                         vis[C[k]] = 1;
107             }
108         return sum;
109     }
110
111     void dance( int k )
112     {
113         int mark, mmin = inf;
114         int tmp = k + h();
115         if ( tmp >= fin || tmp > K )
116             return;
117         if ( R[0] == 0 )
118         {
119             if ( k < fin )
120                 fin = k;
121             return;
122         }
123
124         for ( int i = R[0]; i != 0; i = R[i] )
125             if ( mmin > S[i] )
126             {
127                 mmin = S[i];
128                 mark = i;
129             }
130
131         for ( int i = D[mark]; i != mark; i = D[i] )
132         {
133             remove(i);
134             for ( int j = R[i]; j != i; j = R[j] ) remove(j);
135             dance(k+1);
136             for ( int j = R[i]; j != i; j = R[j] ) resume(j);
137             resume(i);
138         }
139     }
140 }dlx;
141
142 int cnt;
143 int g[62][2];
144
145 struct mmap {
146     int x, y;
147     LL dist;
148     bool operator < ( const mmap &a ) const
149         { return dist < a.dist; }
150 }node[62*62];
151
152 LL getdist( int i, int j )
153 {
154     LL x = abs(g[i][0]-g[j][0]);
155     LL y = abs(g[i][1]-g[j][1]);
156     return x+y;
157 }
158
159 void init( int n )
160 {
161     cnt = 0;
162     for( int i = 1; i <= n; i++ )
163         scanf("%d %d", &g[i][0], &g[i][1] );
164     for ( int i = 1; i <= n; i++ )
165         for ( int j = i; j <= n; j++ )
166         {
167             node[cnt].x = i; node[cnt].y = j;
168             node[cnt++].dist = getdist(i,j);
169         }
170     sort(node, node+cnt);
171 }
172
173 bool judge( int n, int k, LL mid )
174 {
175     dlx.init(n, n); dlx.fin = k+1;
176
177     for ( int i = 0; i < cnt; i++ )
178     {
179         if ( node[i].dist > mid ) break;
180
181         dlx.link( node[i].x, node[i].y );
182         if ( node[i].x != node[i].y )
183             dlx.link( node[i].y, node[i].x );
184     }
185
186     dlx.dance(0);
187     if ( dlx.fin <= k )
188         return true;
189     else
190         return false;
191 }
192
193 LL solve( int n, int k )
194 {
195     LL mid, lhs = 0, rhs = cnt;
196     while ( lhs <= rhs )
197     {
198         mid = (lhs+rhs)>>1;
199         if ( judge(n,k,node[mid].dist) )
200             rhs = mid-1;
201         else
202             lhs = mid+1;
203     }
204
205     if ( judge(n,k,node[lhs].dist) )
206         return node[lhs].dist;
207     else
208         return node[rhs].dist;
209 }
210
211 int main()
212 {
213     //freopen("F:\\cpp\\test.txt", "r", stdin );
214
215     int T; cin >> T;
216     int n, k, cnt = 1;
217     while (T--)
218     {
219         scanf("%d %d", &n, &k);
220         N = n; K = k;
221         init(n);
222         printf("Case #%d: %lld\n", cnt++, solve(n,k));
223     }
224
225     return 0;
226 }

View Code

  7.ZOJ 3122

  16个数字的数独,和9个数字的数独其实一样,这次加了注释,终于理解了...然后dlx范围老是调不好

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <vector>
  5 #include <string>
  6 #include <algorithm>
  7 #include <math.h>
  8 #include <time.h>
  9
 10 #define SIGMA_SIZE 26
 11 #define lson rt<<1
 12 #define rson rt<<1|1
 13 #pragma warning ( disable : 4996 )
 14
 15 using namespace std;
 16 typedef long long LL;
 17 inline LL LMax(LL a,LL b)      { return a>b?a:b; }
 18 inline LL LMin(LL a,LL b)      { return a>b?b:a; }
 19 inline int Max(int a,int b)    { return a>b?a:b; }
 20 inline int Min(int a,int b)       { return a>b?b:a; }
 21 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
 22 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
 23 const LL INF = 0x3f3f3f3f3f3f3f3f;
 24 const LL mod  = 1000000007;
 25 const double eps = 1e-8;
 26 const int inf  = 0x3f3f3f3f;
 27 const int maxk = 1e5;
 28 const int maxn = 1030;
 29
 30 //行:16x16x16=4096表示每个格子有16种选择
 31 //列:(16x16)x3=768,表示16行16列16小块每个各有16种数字单独存在
 32 //列:还要加上768+16x16=1024,表示每个格子只能有一个数字
 33
 34 struct DLX {
 35     int n, m, size, fin;
 36     int U[maxk], D[maxk], L[maxk], R[maxk];//上下左右
 37     int head[maxk], S[maxk];                //分别存每一行第一个1的点的标号和每一列1的个数
 38     int row[maxk], col[maxk], ans[maxk];    //row,col表示第size个点在哪一行/列
 39
 40
 41     void init( int _n, int _m )
 42     {
 43         n = _n; m = _m;
 44         for ( int i = 0; i <= m; i++ )    //初始化第一行(人为增加的虚拟行)
 45         {
 46             S[i] = 0;
 47             U[i] = D[i] = i;
 48             L[i] = i-1;
 49             R[i] = i+1;
 50         }
 51         R[m] = 0; L[0] = m;        //第一行的最后一个元素指向第一个
 52         size = m;                //从m开始以后都是普通节点
 53         memset( head, -1, sizeof(head) );
 54         head[0] = 0;
 55     }
 56
 57     void link( int r, int c )
 58     {
 59         size++;                    //得到新的点标号
 60         col[size] = c;            //第size个点在第c列
 61         row[size] = r;            //第size个点在第r行
 62         S[c]++;                    //第c列1的个数+1
 63
 64                                    //组成一个环,和下面左右一样的插法
 65         D[size] = D[c];
 66         U[size] = c;
 67         U[D[c]] = size;
 68         D[c] = size;
 69
 70         //如果该行没有为1的节点
 71         if ( head[r] < 0 ) head[r] = L[size] = R[size] = size;
 72         else
 73         {
 74             //组成一个环,插在head[r]和head[r]右边那个元素中间
 75             R[size] = R[head[r]];
 76             L[R[size]] = size;
 77             L[size] = head[r];
 78             R[head[r]] = size;
 79         }
 80     }
 81
 82     void remove( int c )   //删除列c及其所在行
 83     {
 84         L[R[c]] = L[c]; R[L[c]] = R[c];                //c的左右两个节点互相连接
 85         for ( int i = D[c]; i != c; i = D[i] )        //屏蔽c列
 86             for ( int j = R[i]; j != i; j = R[j] )
 87             {
 88                 U[D[j]] = U[j];
 89                 D[U[j]] = D[j];
 90                 --S[col[j]];        //j所在的列的1的数目数减少
 91             }
 92     }
 93
 94     void resume( int c )
 95     {
 96         for ( int i = U[c]; i != c; i = U[i] )
 97             for ( int j = L[i]; j != i; j = L[j] )
 98             {
 99                 U[D[j]] = D[U[j]] = j;
100                 ++S[col[j]];
101             }
102         L[R[c]] = R[L[c]] = c;
103     }
104
105     bool dance( int d )
106     {
107         if ( R[0] == 0 ) //第0行没有节点
108         {
109             fin = d;
110             return true;
111         }
112
113         //找出含1数目最小的一列
114         int mark = R[0];
115         for ( int i = R[0]; i != 0; i = R[i] )
116             if ( S[i] < S[mark] )
117                 mark = i;
118
119         remove(mark);    //移除列mark的1的对应行
120         for ( int i = D[mark]; i != mark; i = D[i] )
121         {
122             ans[d] = row[i];
123             //移除该行的1的对应列
124             for ( int j = R[i]; j != i; j = R[j] )
125                 remove(col[j]);
126
127             if ( dance(d+1) )
128                 return true;
129
130             //倒着恢复
131             for ( int j = L[i]; j != i; j = L[j] )
132                 resume(col[j]);
133         }
134         resume(mark);
135         return false;
136     }
137 }dlx;
138
139 char mmap[20][20];
140 char sudoku[20][20];
141 struct node {
142     int x, y, k;
143 }e[maxk];
144
145
146 void init()
147 {
148     //4096行,1024列
149     dlx.init(4096,1024);
150     int row = 0;
151
152     for ( int i = 1; i <= 16; i++ )
153         for ( int j = 1; j <= 16; j++ )
154         {
155             if ( mmap[i][j] == '-' )
156                 for (int k = 1; k <= 16; k++ )
157                 {
158                     row++;
159                     dlx.link(row, (i-1)*16+j );                            //第i行第j个格子已经填了数字
160                     dlx.link(row, 256+(i-1)*16+k);                        //第i行已经填了数字k
161                     dlx.link(row, 512+(j-1)*16+k);                        //第j列已经填了数字k
162                     dlx.link(row, 768+(((i-1)/4)*4 + (j-1)/4)*16+k);    //第xxx个格子已经填了数字k
163                     e[row].x = i; e[row].y = j; e[row].k = k;
164                 }
165             else
166             {
167                 row++;
168                 int k = mmap[i][j] - 'A' + 1;
169                 dlx.link(row, (i-1)*16+j);
170                 dlx.link(row, 256+(i-1)*16+k);
171                 dlx.link(row, 512+(j-1)*16+k);
172                 dlx.link(row, 768+(((i-1)/4)*4 + (j-1)/4)*16+k);
173                 e[row].x = i; e[row].y = j; e[row].k = k;
174             }
175         }
176 }
177
178 int main()
179 {
180     //freopen("F:\\cpp\\test.txt", "r", stdin );
181
182     int cnt = 0;
183     while (1)
184     {
185         if ( ~scanf("%s", mmap[1]+1) )
186         {
187             for ( int i = 2; i <= 16; i++ )
188                 scanf("%s", mmap[i]+1);
189
190             if (cnt++)
191                  printf("\n");
192
193             init();
194             dlx.dance(0);
195
196             int tmp;
197             for ( int i = 0; i < dlx.fin; i++ )
198             {
199                 tmp = dlx.ans[i];
200                 sudoku[e[tmp].x-1][e[tmp].y-1] = e[tmp].k + 'A' - 1;
201                 sudoku[e[tmp].x-1][16] = '\0';
202             }
203             for ( int i = 0; i < 16; i++ )
204                 printf("%s\n", sudoku[i]);
205         }
206         else
207             break;
208     }
209 }

View Code

转载于:https://www.cnblogs.com/chaoswr/p/9016739.html

kuangbin带我飞QAQ DLX之一脸懵逼相关推荐

  1. 只花5-10分钟评审,还不提供拒稿理由,IJCAI就“枪毙”42%论文,网友:一脸懵逼...

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 十三 发自 凹非寺 量子位 报道 | 公众号 QbitAI 今年的IJCAI,真可谓是 ...

  2. 重磅!IJCAI 2020 好狠,超四成论文未经全文评审就out!被拒作者:一脸懵逼,反馈意见呢?...

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! IJCAI-PRICAI 2020,第29届国际人工智能联合会议和第17届环太平洋 ...

  3. 一脸懵逼学习Hadoop中的序列化机制——流量求和统计MapReduce的程序开发案例——流量求和统计排序...

    一:序列化概念 序列化(Serialization)是指把结构化对象转化为字节流. 反序列化(Deserialization)是序列化的逆过程.即把字节流转回结构化对象. Java序列化(java.i ...

  4. 2020全国高考作文题出炉!网友:信心满满的点开,一脸懵逼的退出

    7月7日,2020年这个特别的高考如期来临,伴随着多地的暴雨,考生们完成了第一门的语文考试.11点半结束后,各省的高考作文题目也陆续出来了,一起来看看今年有什么有意思的题目吧. 全国Ⅰ卷 阅读下面的材 ...

  5. python里的点_Python里面这些点,据说80%的新手都会一脸懵逼

    01.函数里面的 *args 1).可变参数 这个是什么鬼,尤其是有其他c,c++语言基础的人,看到这个点,一定懵逼了,难道是指针,两个**又是什么鬼? 其实这个Python里面的函数入参的几种形式, ...

  6. 这段c语言代码牛逼在哪?看得我一脸懵逼!

    有人说C语言是世界上最牛逼的语言,因为操作系统就是用C语言编写的,学好了C才能更好的学习其他编程语言.为此,有人分享了下面一段代码,说是很牛逼的c语言代码,看得小编一脸懵逼.大家来看看,它究竟牛在哪里 ...

  7. 那些曾让我一脸懵逼的python代码

    最近在学习python,选择学习python是有原因的.作为一名不专业的C/C++程序员来说,不掌握另一门脚本语言出门都不好意思和别人打招呼.在浏览别的职位要求时,也常常被"要求掌握一门脚本 ...

  8. 背代码可以学好编程吗?下面的回答看的我一脸懵逼!

    今天小编给大家分享一下关于学习的事情,想必很多小伙伴刚学编程的时候,都会尝试死记硬背代码,或许刚开始确实会有一点效果,但小编我觉得,理解是最重要的,记住代码是必须的,但过程不是背诵,而是反复的敲,反复 ...

  9. 一脸懵逼学习Hadoop-HA机制(以及HA机制的配置文件,测试)

    一脸懵逼学习Hadoop-HA机制(以及HA机制的配置文件,测试) 1:能否让两个NameNode都正常影响客户端请求? 应该让两个NameNode节点在某个时间只能有一个节点正常影响客户端请求,相应 ...

最新文章

  1. 海思3559A上编译OpenCV4.1.0源码操作步骤
  2. 七个最流行的Python神经网络库
  3. Java 获取 Julian Day (Calendar)
  4. Sql Server 按格式输出日期
  5. Centos 下安装redmine及设置发送邮件功能
  6. 机器学习(一) 基于sklearn库的数据集划分(交叉验证)
  7. 9、play中缓存的使用
  8. VMware Workstation 8 技巧集
  9. dumpbin的使用
  10. Visual studio 代码管理工具Git
  11. SpringBoot中的约定优于配置
  12. ubuntu中eclipse无法识别android手机问题
  13. 使用ceph-deploycep集群部署,并用3个磁盘作为专用osd
  14. excel怎么批量插行_excel如何批量在文字前加上固定文字
  15. Android 腾讯 云通信 用户头像更新
  16. 一缕烟香起 静中闻鸿蒙,泰山香缘好抽吗?泰山香缘口感评测
  17. [游戏数据表]泰拉瑞亚Terraria 全物品属性表
  18. 微信「看一看」多模型内容策略与召回
  19. 安装radis看我就可以了
  20. 关于eBPF与可观测性,你想知道的都在这里

热门文章

  1. 征战蓝桥 —— 2013年第四届 —— C/C++A组第8题——买不到的数目
  2. 排序算法 —— 选择排序
  3. 【机器视觉】 Halcon批量加载图像
  4. 【Tools】TortoiseGit安装图解
  5. 用计算机弹奏hop,关于职称计算机Photohop模拟练习题参考
  6. 51nod 1785 数据流中的算法 (方差计算公式)
  7. java 学习笔记2022.1.26
  8. 1032 挖掘机技术哪家强 (20 分)(c语言)
  9. stm32存储结构 存储器映射
  10. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 F- 1 + 2 = 3? (好难的找规律题)