POJ 3074 Sudoku 舞蹈链

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <cstring>

#define INF 100000000
using namespace std;
#define maxn 10000
#define maxnode 270000

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[100];
	void init(int q) {
        n = q;
        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;
    }    

	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[col[j]];
            }
    }  

	void restore(int c) {
        for(int i = U[c]; i != c; i = U[i])
            for(int j = L[i]; j != i; j = L[j]) {
                ++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(int i = R[0];i != 0;i = R[i]){
            if(S[i] < S[c]){
                c = i;
            }
        }
		remove(c);
		for(int i = D[c]; i != c;i = D[i]){
			ans[d] = row[i];
		 	for(int j = R[i]; j != i; j = R[j]) remove(col[j]);
			if(dfs(d+1)) return true;
			for(int j = L[i]; j != i; j = L[j]) restore(col[j]);
		}
		restore(c);
		return false;
	}
};
char puzzle[11][11];
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*81+b*9+c+1;
}
void decode(int code,int &a,int &b,int &c){
	code --;
	c = code%9;
	code /= 9;
	b = code%9;
	code /= 9;
	a = code;
}
char ch[100];
int len[100];
DLX solver;
int main(){
	while(scanf("%s",ch)!=EOF){
		if(strcmp(ch,"end")== 0) break;
		solver.init(324);
		for(int i = 0;ch[i];i++){
			puzzle[i/9][i%9] = ch[i];

		}
		for(int r = 0;r < 9;r++){
			for(int c = 0;c < 9;c++){
				for(int k = 0;k < 9;k++){
					if(puzzle[r][c] == '.' || puzzle[r][c] == k + '1'){
						vector<int> vec;
						vec.push_back(encode(SLOT,r,c));
						vec.push_back(encode(ROW,r,k));
						vec.push_back(encode(COL,c,k));
						vec.push_back(encode(SUB,((r/3)*3+c/3),k));
						solver.addRow(encode(r,c,k),vec);
					}
				}
			}
		}

		solver.dfs(0);
		for(int i = 0;i < solver.ansd;i++){
			int r,c,v;
			decode(solver.ans[i],r,c,v);
			puzzle[r][c] = v;
		}

		for(int i = 0;i < 81;i++){
			printf("%c",puzzle[i/9][i%9]+'1');
		}cout << endl;

	}
	return 0;
}

时间: 2024-08-29 09:15:48

POJ 3074 Sudoku 舞蹈链的相关文章

poj 3074 Sudoku(Dancing Links)

Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8152   Accepted: 2862 Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . . . 6 7 3 5 . . .

POJ 3074 Sudoku (DLX)

Sudoku Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3074 Appoint description:  System Crawler  (2015-04-18) Description In the game of Sudoku, you are given a large 9 × 9 grid divided into sm

poj 3074 Sudoku dlx解数独

分析: dlx是从数据结构角度优化01矩阵精确覆盖和重复覆盖的数据结构,它用十字链表只存贮矩阵中的非0元,而01矩阵精确覆盖dfs过程中矩阵会越来越稀疏而且每次恢复现场会浪费大量时间,dlx恰好能解决这两个问题.本题关键是将数独问题转化为01矩阵精确覆盖.数独转化为精确覆盖问题的方法还是参照Knuth的论文,如果读取到一个格子是空的,那么加9行,分别表示这个格子填1到9这9个数字,如果读取到的格子是一个数字,那么就加一行就可以了,然后列有9*9*4列,前81列表示这一行表示填的是第i行第j列的格

POJ 3074 Sudoku DLX精确覆盖

DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: 2945 Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . .

(简单) POJ 3074 Sudoku, DLX+精确覆盖。

Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . . . 6 7 3 5 . . . . . . . 2 9 3 . 5 6 9 2 . 8 . . . . . . . . . . . 6 . 1 7 4 5 . 3 6 4 . . . . . . . 9 5 1

POJ 1084 Square Destroyer【舞蹈链】【重复覆盖】

建模很容易就能说清楚,但我一直想不出来. 要问为什么的话可能是因为这题要先预处理出来所有正方形,而我没做过要预处理的舞蹈链的题.所以想不到. 那就是预处理出来所有正方形,用一个long long来表示一个正方形,这个正方形有没有包含id这条边就用 (1<<id)&num判断.那怎么预处理所有正方形呢,枚举边长1-n的正方形,然后再枚举这个正方形左上方的顶点就能做出来. 然后就能建模了,火柴是行,所有按现有火柴能拼出来的正方形是列,与其说是精准覆盖倒也可以说是全部破坏. http://e

HDU 4069 Squiggly Sudoku【舞蹈链】【样例坑】

建模思路跟之前的一样,宫的话dfs搜索一下找联通分量就行,好像也没有更好的办法,有的话请评论哈orz --因为舞蹈链一般找到解以后就直接跳出了,所以ans数组就是ans不会再变.但这题让找一下有没有多组解,所以就不能找到一个解后直接跳出.就有一个小坑是都搜完后ans数组可能不是合法ans,所以找到第一个解的时候要单独存一下才能ac --但这个样例就是如果中间不存一下ans数组的话,样例还是能过... --那应该就是正好最后一次枚举的时候找到了这个解?? --不然的话它回溯的时候枚举下一个可能会覆

POJ 3435 Sudoku Checker

Description The puzzle game of Sudoku is played on a board of N2 × N2 cells. The cells are grouped in N × N squares of N × N cells each. Each cell is either empty or contains a number between 1 and N2. The sudoku position is correct when numbers in e

poj 3076 Sudoku dlx解数独

16*16的数独,类似poj 3074. //poj 3076 //sep9 #include <cstdio> #include <cstdlib> #define INT_MAX 2147483647 using namespace std; const int col_num=16*16*4; const int row_num=16*16*16+10; const int head=0; const int MAX=row_num*4+col_num+10; const i