Spoj 1771
来源:互联网 发布:数据库逻辑结构 编辑:程序博客网 时间:2024/05/19 12:41
题意:
跟n皇后一样,就是有些地方已经放了皇后,且范围是n <= 50
我的模板从 fp_hzq神牛哪里学到的
他的博客: http://blog.csdn.net/fp_hzq/article/details/6797150
从他的博客学到很多东西
这道题与普通的精确覆盖不同,有些地方不用全部覆盖,只要覆盖行和列,对角线不用全部覆盖,
只要做一个约束条件,而我采用的判断是,当R[0] >2*n时就结束,意思是将行和列覆盖完就结束了,选取的列也是 <= 2 * n
代码如下:
#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define N 55#define ROW N * N#define COLUMN N * 2 + (2 * N - 1) * 2 + 10#define AREA ROW * COLUMNint U[AREA], D[AREA], L[AREA], R[AREA], C[AREA];int int P[AREA], X[AREA], Y[AREA];int H[ROW], S[COLUMN], Q[ROW];int e;void init(int n, int m){ for(int i = 0; i <= n; i++) H[i] = -1; for(int i = 0; i <= m; i++){ S[i] = 0; U[i] = D[i] = i; L[i+1] = i; R[i] = i + 1; } R[e = m] = 0;}void remove(int c){ L[R[c]] = L[c]; R[L[c]] = R[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], -- S[C[j]];}void resume(int c){ for(int i = U[c]; i != c; i = U[i]) for(int j = L[i]; j != i; j = L[j]) U[D[j]] = D[U[j]] = j, ++ S[C[j]]; L[R[c]] = R[L[c]] = c;}int n;int Dance(int k){ if(R[0] > 2 * n){//(k >= n) for(int i = 0; i < k; i++){ P[Y[Q[i]]] = X[Q[i]]; } for(int i = 1; i <= n; i++) { printf("%d",P[i]); if(i != n) printf(" "); } printf("\n"); return 1; } int c, tmp = ROW; for(int i = R[0]; i != 0; i = R[i]) if(i <= 2 * n) {//(i <= n) if(tmp > S[i]) tmp = S[c = i]; } else { break; } remove(c); for(int i = D[c]; i != c; i = D[i]){ Q[k] = i; for(int j = R[i]; j != i; j = R[j]) remove(C[j]); if(Dance(k + 1)) return 1; for(int j = L[i]; j != i; j = L[j]) resume(C[j]); } resume(c); return 0;}void Link(int r,int c,int i, int j){ C[++e] = c; ++S[c]; Y[e] = i; X[e] = j; D[e] = D[c]; U[D[c]] = e; U[e] = c; D[c] = e; if(H[r] < 0) H[r] = L[e] = R[e] = e; else { R[e] = R[H[r]]; L[R[H[r]]] = e; L[e] = H[r]; R[H[r]] = e; }}int maze[N][N];int c[4];void find(int x, int y, int n){ c[0] = x; c[1] = n + y; c[2] = n * 2 + (x + y - 1); x = n - x + 1; c[3] = n * 2 + (2 * n - 1) + (x + y - 1);}int main(){// freopen("in","r",stdin); while(scanf("%d",&n) != -1){ memset(maze,0,sizeof(maze)); memset(ma,0,sizeof(ma)); int x, y; x = n * n; y = 2 * n + (2 * n - 1) * 2; init(x,y); for(int i = 1; i <= n; i++){ int tmp; scanf("%d",&tmp); if(tmp == 0) continue; maze[i][tmp] = 2; int s = i + tmp; for(int j = 1; j <= n; j++) if(maze[i][j] ==0) maze[i][j] = 1; for(int j = 1; j <= n; j++) if(maze[j][tmp] == 0) maze[j][tmp] = 1; for(x = 1; x <= n; x++){ y = s - x; if(y < 1 || y > n) continue; if(maze[x][y] == 0) maze[x][y] = 1; } s = tmp - i; for(x = 1; x <= n; x++){ y = x + s; if(y < 1 || y > n) continue; if(maze[x][y] == 0) maze[x][y] = 1; } } for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) if(maze[i][j] != 1) { find(i, j, n); for(int k = 0; k < 4; k++) Link((i-1) * n + j,c[k],i,j); } Dance(0); } return 0;}
- Spoj 1771
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- java经典算法四十题
- .net c# 自学日记之 类 对象 属性 方法 的 包 并发 多线程 多态
- C#正则表达式快速入门
- java经典算法四十题
- hdu 1203 DP
- Spoj 1771
- java经典算法四十题
- IOS UITableView学习Demo
- 在使用vs2010调试时大量出现iso_whid,HR PROPAGATED 信息
- java经典算法四十题
- perl解析ip的经典方法
- java经典算法四十题
- Apache与Nginx的优缺点比较
- java经典算法四十题