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

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值