zoukankan      html  css  js  c++  java
  • 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 . . . 6 7 3 5
    . . . . . . . 2 9
    3 . 5 6 9 2 . 8 .
    . . . . . . . . .
    . 6 . 1 7 4 5 . 3
    6 4 . . . . . . .
    9 5 1 8 . . . 7 .
    . 8 . . 6 5 3 4 .

    Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.

    Input

    The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.

    Output

    For each test case, print a line representing the completed Sudoku puzzle.

    Sample Input

    .2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
    ......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
    end

    Sample Output

    527389416819426735436751829375692184194538267268174593643217958951843672782965341
    416837529982465371735129468571298643293746185864351297647913852359682714128574936

    Source

    [Submit]   [Go Back]   [Status]   [Discuss]




    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int N=9;
    const int maxn=N*N*N+10;
    const int maxm=N*N*4+10;
    const int maxnode=maxn*4+maxm+10;
    
    char sudoku[maxn];
    
    struct DLX
    {
    	int n,m,size;
    	int U[maxnode],D[maxnode],L[maxnode],R[maxnode],Row[maxnode],Col[maxnode];
    	int H[maxnode],S[maxnode];
    	int ansd,ans[maxn];
    	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)
    	{
    		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 resume(int c)
    	{
    		for(int i=U[c];i!=c;i=U[i])
    			for(int j=L[i];j!=i;j=L[j])
    				++S[Col[U[D[j]]=D[U[j]]=j]];
    		L[R[c]]=R[L[c]]=c;
    	}
    	bool Dance(int d)
    	{
    		if(R[0]==0)
    		{
    			for(int i=0;i<d;i++) sudoku[(ans[i]-1)/9]=(ans[i]-1)%9+'1';
    			printf("%s
    ",sudoku);
    			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(Dance(d+1)) return true;
    			for(int j=L[i];j!=i;j=L[j]) resume(Col[j]);
    		}
    		resume(c);
    		return false;
    	}
    };
    
    DLX dlx;
    
    void place(int& r,int& c1,int& c2,int& c3,int& c4,int i,int j,int k)
    {
    	r=(i*N+j)*N+k;
    	c1=i*N+j+1;
    	c2=N*N+N*i+k;
    	c3=N*N*2+N*j+k;
    	c4=N*N*3+((i/3)*3+(j/3))*N+k;
    }
    
    int main()
    {
    	while(scanf("%s",sudoku)!=EOF)
    	{
    		if(sudoku[2]=='d') break;
    		dlx.init(N*N*N,N*N*4);
    		for(int i=0;i<N;i++)
    		{
    			for(int j=0;j<N;j++)
    			{
    				for(int k=1;k<=N;k++)
    				{
    					if(sudoku[i*N+j]=='.'||sudoku[i*N+j]==k+'0')
    					{
    						int r,c1,c2,c3,c4;
    						place(r,c1,c2,c3,c4,i,j,k);
    						dlx.Link(r,c1);
    						dlx.Link(r,c2);
    						dlx.Link(r,c3);
    						dlx.Link(r,c4);
    					}
    				}
    			}
    		}
    		dlx.Dance(0);
    	}
    	return 0;
    }
    


  • 相关阅读:
    热爱自己的工作
    python 类型转换操作
    使用Python实现Telnet远程登录
    使用Python为程序添加右键菜单打开方式
    【Django实例】序言
    【转】Windows右键菜单设置与应用技巧
    【转】浅谈以太网帧格式
    Beyond Compare脚本:比较文件并生成html格式的差异报告
    【转】C语言中的位域、字节序、比特序、大小端
    【转】tcpdump抓取TCP/IP数据包分析
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6917322.html
Copyright © 2011-2022 走看看