ZOJ 3209 Treasure Map
2015-04-24 00:54
169 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3209
dancing links 每个点作为一列。
每个块作为一行。
不知道为什么插节点的时候 如果把循环写成
dancing links 每个点作为一列。
每个块作为一行。
不知道为什么插节点的时候 如果把循环写成
for(int i = y1+1; i <= y2; i++){ //行 for(int j = x1+1; j <= x2; j++){ //列 } } 然后col = (y-1)*n+x就会超时。
#include <iostream> #include <cstring> #include <cstdio> #include <string> #include <iomanip> using namespace std; int T, n, m, p, x1, y1, x2, y2; #define maxn 510*35*35 int R[maxn], L[maxn], U[maxn], D[maxn]; int H[maxn], C[maxn], colsum[999]; int head, cnt, ans; void addnode(int i, int j, int h, int rowhead, int sum, int pre){ int col = j+(i-1)*m; //cout<<col<<" "; cnt++; H[cnt] = h; C[cnt] = col; if(sum == 1){ R[cnt] = cnt; L[cnt] = cnt; } else if(sum == 2){ R[pre] = cnt; R[cnt] = pre; L[pre] = cnt; L[cnt] = pre; } else{ R[cnt] = rowhead; R[pre] = cnt; L[cnt] = pre; L[rowhead] = cnt; } D[U[col]] = cnt; U[cnt] = U[col]; D[cnt] = col; U[col] = cnt; colsum[col]++; } void init(){ head = cnt = 0; ans = 510; //最多就是500块。 R[head] = 1; L[head] = n*m; U[head] = head; D[head] = head; H[head] = 0; C[head] = 0; memset(colsum, 0, sizeof(colsum)); for(int i = 1; i <= n*m; i++){ cnt++; U[cnt] = D[cnt] = cnt; H[cnt] = 0; C[cnt] = i; if(i == n*m){ R[cnt-1] = cnt; L[cnt] = cnt-1; R[cnt] = head; } else{ R[cnt-1] = cnt; L[cnt] = cnt-1; } } for(int cc = 1; cc <= p; cc++){ scanf("%d%d%d%d", &x1, &y1, &x2, &y2); int sum = 0, rowhead = -1, pre; for(int i = x1+1; i <= x2; i++){ //行 for(int j = y1+1; j <= y2; j++){ //列 sum++; addnode(i, j ,cc, rowhead, sum, pre); if(rowhead == -1) rowhead = cnt; pre = cnt; } } } } void remove(int c){ R[L[c]] = R[c]; L[R[c]] = L[c]; for(int i = D[c]; i != c; i = D[i]){ for(int j = R[i]; j != i; j = R[j]){ U[D[j]] = U[j]; D[U[j]] = D[j]; colsum[C[j]]--; } } } void resume(int c){ R[L[c]] = c; L[R[c]] = c; for(int i = D[c]; i != c; i = D[i]){ for(int j = R[i]; j != i; j = R[j]){ U[D[j]] = j; D[U[j]] = j; colsum[C[j]]++; } } } void dance(int k){ if(k >= ans) return; int c = R[head]; if(c == head){ ans = k; return; } int min = 9999999; for(int i = R[head]; i != head; i = R[i]){ if(colsum[i] <= min){ min = colsum[i]; c = i; } } remove(c); for(int i = D[c]; i != c; i = D[i]){ for(int j = R[i]; j != i; j = R[j]) remove(C[j]); dance(k+1); for(int j = L[i]; j != i; j = L[j]) resume(C[j]); //要写成L } resume(c); return ; } int main(){ scanf("%d", &T); while(T--){ scanf("%d%d%d", &n, &m, &p); //n是列,m是行。 init(); dance(0); if(ans == 510) printf("-1\n"); else printf("%d\n", ans); } return 0; }
相关文章推荐
- ZOJ 3209 Treasure Map (DLX精确覆盖)
- zoj 3209 Treasure Map (dancing links)
- ZOJ 3209 Treasure Map (DLX精确覆盖问题)
- ZOJ 3209 Treasure Map(DLX精确覆盖)
- ZOJ 3209 Treasure Map
- ZOJ 3209 Treasure Map 精确覆盖
- ZOJ 3209 Treasure Map(Dancing Links)
- ZOJ 3209 Treasure Map (Dancing Links 精确覆盖 )
- [ACM] ZOJ 3209 Treasure Map ( Dancing Links 精确覆盖,矩形覆盖)
- ZOJ-3209-Treasure Map【6th浙江省赛】【DLX精确覆盖】【模板题】
- ZOJ 3209 Treasure Map
- ZOJ3209 Treasure Map —— Danc Links 精确覆盖
- zoj 3209 Treasure Map 最小覆盖问题 dancing links
- ZOJ 3209 Treasure Map
- (简单) ZOJ 3209 Treasure Map , DLX+精确覆盖。
- ZOJ3209-Treasure Map
- zoj 3209.Treasure Map(DLX精确覆盖)
- ZOJ 3209 Treasure Map(Dancing Links)(精确覆盖问题)
- zoj - 3209 - Treasure Map(精确覆盖DLX)
- zoj - 3209 - Treasure Map(精确覆盖DLX)