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;
}

View Code

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;
}

View Code

ZOJ 3209

题目:给出一张地图的若干个碎片,要求用最少的碎片恢复原地图.

思路:基本还是裸的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;elseansd=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;
}

View Code

FZU 1686

题目;每次可以攻击一个矩形子矩阵,问最少攻击多少次达到目标.

思路:可重复覆盖的DLX和精确覆盖版的主要有这么几个区别

1)删除的时候,精确覆盖要求删去所有当前行已经覆盖的列,以及在已覆盖列上还有元素的所有行,而可重复覆盖只是删除已经覆盖的所有列.

2)由于可重复覆盖通常要求解最小步数,所以需要一个剪枝.

/*
* @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 MaxM = 15*15+10;//width
const int MaxN = 15*15+10;//hight
const int maxnode = MaxN * MaxM;
const int INF = 0x3f3f3f3f;
struct DLX{int n,m,size;intU[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];int H[MaxN],S[MaxM];int ansd;void init(int _n,int _m){n = _n;m = _m;for(int i = 0;i <= m;i++){S[i] = 0;U[i] = D[i] = i;L[i] = i-1;R[i] = i+1;}R[m] = 0; L[0] = m;size = m;for(int i = 1;i <= n;i++)H[i] = -1;}void Link(int r,int c){++S[Col[++size]=c];Row[size] = r;D[size] = D[c];U[D[c]] = size;U[size] = c;D[c] = size;if(H[r] < 0)H[r] = L[size] = R[size] = size;else{R[size] = R[H[r]];L[R[H[r]]] = size;L[size] = H[r];R[H[r]] = size;}}void remove(int c){for(int i = D[c];i != c;i = D[i])L[R[i]] = L[i], R[L[i]] = R[i];}void resume(int c){for(int i = U[c];i != c;i = U[i])L[R[i]] = R[L[i]] = i;}bool v[MaxM];int f(){int ret = 0;for(int c = R[0]; c != 0;c = R[c])v[c] = true;for(int c = R[0]; c != 0;c = R[c]){if(v[c]){ret++;v[c] = false;for(int i = D[c];i != c;i = D[i]){for(int j = R[i];j != i;j = R[j])v[Col[j]] = false;}}}return ret;}void Dance(int d=0){if(d + f() >= ansd)return;if(R[0] == 0){if(d < ansd)ansd = d;return;}int c = R[0];for(int i = R[0];i != 0;i = R[i]){if(S[i] < S[c])c = i;}for(int i = D[c];i != c;i = D[i]){remove(i);for(int j = R[i];j != i;j = R[j])remove(j);Dance(d+1);for(int j = L[i];j != i;j = L[j])resume(j);resume(i);}}
}dan;int n,m;
int grid[20][20];
int id[20][20];
int main(){freopen("/home/files/CppFiles/in","r",stdin);//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);while(cin>>n>>m){int sz=1;for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%d",&grid[i][j]);if(grid[i][j]) id[i][j]=sz++;}}dan.init(n*m,sz-1);int n1,m1;scanf("%d%d",&n1,&m1);sz=1;for(int i=0;i<n;i++){for(int j=0;j<m;j++){for(int x=0;x<n1;x++){for(int y=0;y<m1;y++){if(i+x<n&&j+y<m&&grid[i+x][j+y]){dan.Link(sz,id[i+x][j+y]);}}}sz++;}}dan.ansd=INF;dan.Dance();printf("%d\n",dan.ansd);}return 0;
}

View Code

转载于:https://www.cnblogs.com/Cw-trip/p/4836841.html

UVALive 2659+HUST 1017+ZOJ 3209+FZU 1686 (DLX相关推荐

  1. fzu 1686(DLX 重复点覆盖)

    可以重复的点覆盖, 写法和一般的DLX 很相似,但是在找到选择一行的时候,只删去这一行上所有点的列.   还要注意的是启发函数起了很大的剪枝作用. Problem 1686 神龙的难题 Accept: ...

  2. ZOJ 3209 Treasure Map DLX

    用最少的矩阵覆盖n*m的地图.注意矩阵不能互相覆盖. 这里显然是一个精确覆盖,但因为矩阵拼接过程中,有公共的边,这里须要的技巧就是把矩阵的左边和以下截去一个单位. #include <stdio ...

  3. zoj 3209 Dancing links/hust 1017

    Dancing links的题目. 具体的dancing links的介绍 看:http://blog.csdn.net/sunny606/article/details/7833551 思想还是好理 ...

  4. FZU 1686 神龙的难题(DLX反复覆盖)

    FZU 1686 神龙的难题 题目链接 题意:中文题 思路:每个1看成列,每个位置作为左上角的矩阵看成行.dlx反复覆盖就可以 代码: #include <cstdio> #include ...

  5. Dancing Link --- 模板题 HUST 1017 - Exact cover

    1017 - Exact cover Problem's Link:   http://acm.hust.edu.cn/problem/show/1017 Mean: 给定一个由0-1组成的矩阵,是否 ...

  6. LA 2659 poj 3076 zoj 3122 Sudoku(精确覆盖 + DLX)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  7. FZU - 1686 神龙的难题 (舞蹈链,可重覆盖)

    这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们 ...

  8. FZU 1686 神龙的难题(重复覆盖问题舞蹈链)

    题目链接:[kuangbin带你飞]专题三 Dancing Links D - 神龙的难题 题意 Description 这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是 ...

  9. Treasure Map ZOJ - 3209(Dancing Links)

    传送门 题解:首先可以先看下这篇对于Dancing Links的介绍,很好的传送门 然后这个题其实建模很简单的,把n*m的大矩阵转化成一排,然后把那些小矩阵对应起来,之后进行选取,如果可以选出最小集合 ...

  10. [kuangbin]各种各样的题单

    [kuangbin]各种各样的题单 专题1 简单搜索 POJ 1321 POJ 2251 POJ 3278 POJ 3279 POJ 1426 POJ 3126 POJ 3087 POJ 3414 F ...

最新文章

  1. GMS(cts、gsi、vts、gts、ctsv)问题总结
  2. 工作组环境中配置WSUS客户端
  3. imageloader图片基本加载
  4. 英语作文谈谈你对计算机的看法,英语作文:谈谈你对网络语言的看法
  5. 2018年度机器学习50大热门网文
  6. [转载] Python基础之类型转换与算术运算符
  7. Linxu:磁盘分区
  8. 德国THI大学,招聘移动视觉和深度学习研究助理和研究员
  9. 计算机专业考试知识点,2016计算机专业知识:精选知识点练习(126)
  10. 群辉发布RackStation系列机型——RS3621RPxs、RS3621xs+与RS4021xs+
  11. 互联网的未来之下:政权 金权 人权 无关平权
  12. 阿里云IoT规则引擎SQL参考
  13. HikariCP对各Java版本的支持
  14. 多源信息融合_BIM+GIS的深度融合之路
  15. 谷粒学院(十六)OAuth2 | 微信扫码登录 | QQ扫码登录
  16. C++17 实现日期和时间相关编程
  17. 通过PHP使用Google Translate API
  18. php测试页面打开速度,在JS中如何测试目标网站的打开响应速度
  19. 天呐!350道Java面试真题分享
  20. 每日3词 2021-03-14 【old】【new】【count】

热门文章

  1. Android SDK 和 JDK 安装
  2. 什么是Adam/ReLU/YOLO?这里有一份深度学习(.ai)词典
  3. transformer李宏毅讲解视频及decoder讲解
  4. 排序算法之——冒泡排序分析
  5. 每周荐书:高可用架构、解忧程序员、财富自由之路(评论送书)
  6. 容器使用的12条军规——《Effective+STL中文版》试读
  7. 读大师的书 说自己的话——《传世经典书丛评注版》邀你来点评
  8. Windows的设备驱动框架中的上层与下层模块
  9. 深入灵魂的共鸣 (《梦断代码》读后感)
  10. 3.2. tensorflow2实现Wileoxon秩和检验法(下) ——python实战