标签:
UVALive 2659
题目:16*16的数独.试了一发大白模板.
/* * @author: Cwind */ //#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include <cmath> using namespace std; #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0) #define pb push_back #define PB pop_back #define bk back() #define fs first #define se second #define sq(x) (x)*(x) #define eps (1e-6) #define IINF (1<<29) #define LINF (1ll<<59) #define INF (1000000000) #define FINF (1e3) typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> P; const int maxr = 5000; const int maxn = 2000; const int maxnode = 20000; struct DLX { int n, sz; int S[maxn]; int row[maxnode], col[maxnode]; int L[maxnode], R[maxnode], U[maxnode], D[maxnode]; int ansd, ans[maxr]; void init(int n) { this->n = n; for(int i = 0 ; i <= n; i++) { U[i] = i; D[i] = i; L[i] = i-1, R[i] = i+1; } R[n] = 0; L[0] = n; sz = n + 1; memset(S, 0, sizeof(S)); } void addRow(int r, vector<int> &columns) { int first = sz; for(int i = 0; i < columns.size(); i++) { int c = columns[i]; L[sz] = sz - 1; R[sz] = sz + 1; D[sz] = c; U[sz] = U[c]; D[U[c]] = sz; U[c] = sz; row[sz] = r; col[sz] = c; S[c]++; sz++; } R[sz - 1] = first; L[first] = sz - 1; } #define FOR(i,A,s) for(int i = A[s]; i != s; i = A[i]) void remove(int c) { L[R[c]] = L[c]; R[L[c]] = R[c]; FOR(i,D,c) FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; } } void restore(int c) { FOR(i,U,c) FOR(j,L,i) { ++S[col[j]]; U[D[j]] = j; D[U[j]] = j; } L[R[c]] = c; R[L[c]] = c; } bool dfs(int d) { if (R[0] == 0) { ansd = d; return true; } int c = R[0]; FOR(i,R,0) if(S[i] < S[c]) c = i; remove(c); FOR(i,D,c) { ans[d] = row[i]; FOR(j,R,i) remove(col[j]); if(dfs(d+1)) return true; FOR(j,L,i) restore(col[j]); } restore(c); return false; } bool solve(vector<int>& v) { v.clear(); if(!dfs(0)) return false; for(int i = 0; i < ansd; i++) v.push_back(ans[i]); return true; } }solver; const int SLOT=0; const int ROW=1; const int COL=2; const int SUB=3; int encode(int a,int b,int c){ return a*256+b*16+c+1; } char puzzal[20][20]; void decode(vector<int> &ans){ for(int i=0;i<ans.size();i++){ ans[i]--; int c=ans[i]%16;ans[i]/=16; int b=ans[i]%16;ans[i]/=16; int a=ans[i]; puzzal[a][b]=‘A‘+c; } } bool flag=0; int main(){ freopen("/home/files/CppFiles/in","r",stdin); //freopen("test.in","r",stdin); //freopen("test.out","w",stdout); while(scanf("%s",puzzal[0])!=EOF){ for(int i=1;i<16;i++){ scanf("%s",puzzal[i]); } if(flag){ puts(""); }else{ flag=1; } solver.init(1024); for(int r=0;r<16;r++){ for(int c=0;c<16;c++){ for(int v=0;v<16;v++){ if(puzzal[r][c]==‘-‘||puzzal[r][c]==‘A‘+v){ vector<int> columns; columns.pb(encode(SLOT,r,c)); columns.pb(encode(ROW,r,v)); columns.pb(encode(COL,c,v)); columns.pb(encode(SUB,r/4*4+c/4,v)); solver.addRow(encode(r,c,v),columns); } } } } vector<int> ans; solver.solve(ans); decode(ans); for(int i=0;i<16;i++){ for(int j=0;j<16;j++){ printf("%c",puzzal[i][j]); } puts(""); } } return 0; }
HUST 1017
题目:裸精确覆盖,继续套模板.
/* * @author: Cwind */ //#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include <cmath> using namespace std; #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0) #define pb push_back #define PB pop_back #define bk back() #define fs first #define se second #define sq(x) (x)*(x) #define eps (1e-6) #define IINF (1<<29) #define LINF (1ll<<59) #define INF (1000000000) #define FINF (1e3) typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> P; const int maxr = 5000; const int maxn = 2000; const int maxnode = 1e6+3000; struct DLX { int n, sz; int S[maxn]; int row[maxnode], col[maxnode]; int L[maxnode], R[maxnode], U[maxnode], D[maxnode]; int ansd, ans[maxr]; void init(int n) { this->n = n; for(int i = 0 ; i <= n; i++) { U[i] = i; D[i] = i; L[i] = i-1, R[i] = i+1; } R[n] = 0; L[0] = n; sz = n + 1; memset(S, 0, sizeof(S)); } void addRow(int r, vector<int> &columns) { int first = sz; for(int i = 0; i < columns.size(); i++) { int c = columns[i]; L[sz] = sz - 1; R[sz] = sz + 1; D[sz] = c; U[sz] = U[c]; D[U[c]] = sz; U[c] = sz; row[sz] = r; col[sz] = c; S[c]++; sz++; } R[sz - 1] = first; L[first] = sz - 1; } #define FOR(i,A,s) for(int i = A[s]; i != s; i = A[i]) void remove(int c) { L[R[c]] = L[c]; R[L[c]] = R[c]; FOR(i,D,c) FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; } } void restore(int c) { FOR(i,U,c) FOR(j,L,i) { ++S[col[j]]; U[D[j]] = j; D[U[j]] = j; } L[R[c]] = c; R[L[c]] = c; } bool dfs(int d) { if (R[0] == 0) { ansd = d; return true; } int c = R[0]; FOR(i,R,0) if(S[i] < S[c]) c = i; remove(c); FOR(i,D,c) { ans[d] = row[i]; FOR(j,R,i) remove(col[j]); if(dfs(d+1)) return true; FOR(j,L,i) restore(col[j]); } restore(c); return false; } bool solve(vector<int>& v) { v.clear(); if(!dfs(0)) return false; for(int i = 0; i < ansd; i++) v.push_back(ans[i]); return true; } }solver; int n,m; vector<int> columns; vector<int> ans; int main(){ freopen("/home/files/CppFiles/in","r",stdin); //freopen("test.in","r",stdin); //freopen("test.out","w",stdout); while(cin>>n>>m){ solver.init(m); for(int r=1;r<=n;r++){ columns.clear(); int x; scanf("%d",&x); for(int j=0;j<x;j++){ int v; scanf("%d",&v); columns.pb(v); } solver.addRow(r,columns); } ans.clear(); bool f=solver.solve(ans); if(!f){ puts("NO"); continue; } printf("%d",(int)ans.size()); for(int i=0;i<ans.size();i++){ printf(" %d",ans[i]); } puts(""); } return 0; }
题目:给出一张地图的若干个碎片,要求用最少的碎片恢复原地图.
思路:基本还是裸的dlx,搜的时候剪枝一下就好.
/* * @author: Cwind */ //#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include <cmath> using namespace std; #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0) #define pb push_back #define PB pop_back #define bk back() #define fs first #define se second #define sq(x) (x)*(x) #define eps (1e-6) #define IINF (1<<29) #define LINF (1ll<<59) #define INF (1000000000) #define FINF (1e3) typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> P; const int maxr = 5000; const int maxn = 2000; const int maxnode = 1e6+3000; struct DLX { int n, sz; int S[maxn]; int row[maxnode], col[maxnode]; int L[maxnode], R[maxnode], U[maxnode], D[maxnode]; int ansd, ans[maxr]; void init(int n) { this->n = n; for(int i = 0 ; i <= n; i++) { U[i] = i; D[i] = i; L[i] = i-1, R[i] = i+1; } R[n] = 0; L[0] = n; sz = n + 1; memset(S, 0, sizeof(S)); } void addRow(int r, vector<int> &columns) { int first = sz; for(int i = 0; i < columns.size(); i++) { int c = columns[i]; L[sz] = sz - 1; R[sz] = sz + 1; D[sz] = c; U[sz] = U[c]; D[U[c]] = sz; U[c] = sz; row[sz] = r; col[sz] = c; S[c]++; sz++; } R[sz - 1] = first; L[first] = sz - 1; } #define FOR(i,A,s) for(int i = A[s]; i != s; i = A[i]) void remove(int c) { L[R[c]] = L[c]; R[L[c]] = R[c]; FOR(i,D,c) FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; } } void restore(int c) { FOR(i,U,c) FOR(j,L,i) { ++S[col[j]]; U[D[j]] = j; D[U[j]] = j; } L[R[c]] = c; R[L[c]] = c; } void dfs(int d) { if(ansd!=-1&&d>ansd) return; if (R[0] == 0) { if(ansd==-1) ansd = d; else ansd=min(ansd,d); return; } int c = R[0]; FOR(i,R,0) if(S[i] < S[c]) c = i; remove(c); FOR(i,D,c) { ans[d] = row[i]; FOR(j,R,i) remove(col[j]); dfs(d+1); FOR(j,L,i) restore(col[j]); } restore(c); return; } void solve(vector<int>& v) { v.clear(); dfs(0); for(int i = 0; i < ansd; i++) v.push_back(ans[i]); } }solver; int T,n,m,p; vector<int> columns; int main(){ freopen("/home/files/CppFiles/in","r",stdin); //freopen("test.in","r",stdin); //freopen("test.out","w",stdout); cin>>T; while(T--){ cin>>n>>m>>p; solver.init(n*m); for(int r=1;r<=p;r++){ int x1,y1,x2,y2; columns.clear(); scanf("%d%d%d%d",&x1,&y1,&x2,&y2); x1++,y1++; for(int i=x1;i<=x2;i++){ for(int j=y1;j<=y2;j++){ columns.pb((i-1)*m+j); } } solver.addRow(r,columns); } solver.ansd=-1; solver.dfs(0); printf("%d\n",solver.ansd); } return 0; }
UVALive 2659+HUST 1017+ZOJ 3209 (DLX
标签:
原文地址:http://www.cnblogs.com/Cw-trip/p/4836841.html