用舞蹈链实现数独2

输入12 12 12显示答案,如果没有显示就是没有结果

输入13 13 13更换数独开局

输入0-8 0-8 0-9在指定位置放值

输入11 11 11检验数独是否正确

#include
#include
#include//rand函数
#include//srand函数
#include"ConsoleColor.h"
#include
using namespace std;

#define RR 729  //81*9 创建出9个舞蹈链,分别代表填入的数字?
#define CC 324  //81*4 约束条件?
#define INF 1000000000


class node{
public:
	int r,c;
	node *up;
	node *down;
	node *left;
	node *right;
};

class DealWithSudoku{
private:
	int mem1[81+1];//用于存储结果1
	int mem2[81+1];//用于存储结果2
	int *mem;//mem指针指向mem1
	int ch[81];//数独开局数据
	int cnt[CC+1];//用于存储每个列的结点数
	int scnt;//用于存储结果数
	int all_t;//结点数
	node head;//头指针
	node all[RR*CC+99];//所有结点的数组
	node row[RR];//行结点数组
	node col[CC];//列结点数组
public:
	DealWithSudoku(){
		mem=mem1;
		scnt=0;
		memset(cnt,0,sizeof(cnt));//把cnt整个赋值为0
		head.left=&head;
		head.right=&head;
		head.up=&head;
		head.down=&head;
		head.r=RR;
		head.c=CC;
	}//DealWithSudoku
	void initial(){
		mem=mem1;
		scnt=0;
		memset(cnt,0,sizeof(cnt));//把cnt整个赋值为0
		head.left=&head;
		head.right=&head;
		head.up=&head;
		head.down=&head;
		head.r=RR;
		head.c=CC;
	}
	void setCh(int a[][9]){
		int i=-1,j,n=0;
		for(;++i<9;){
			for(j=-1;++j<9;){
				ch[n++]=a[i][j];
			}//for
		}//for
		ch[81]='\0';
		BuildDL();
	}//setCh
	void BuildDL(){
		int i=-1;
		//建立列
		for(;++iright=&col[i];
			col[i].right->left=&col[i];
		}//for
		//建立行
		for(i=-1;++idown=&row[i];
			row[i].down->up=&row[i];
		}//for
		int r,c,val,tr,tc;
		for(i=-1;++iright=row[i].right;
			row[i].right->left=row[i].left;
		}
		solve(1);
	}//BuildDL
	void link(int r,int c){//指定行,指定列插入结点
		cnt[c]++;
		node *t=&all[all_t++];
		t->r=r;
		t->c=c;

		//插入顺序是从行结点往右插入,之前的结点右推
		t->left=&row[r];
		t->right=row[r].right;
		t->left->right=t;
		t->right->left=t;

		//插入顺序是从列结点往下插入,之前的结点下推
		t->up=&col[c];
		t->down=col[c].down;
		t->up->down=t;
		t->down->up=t;
	}
	void remove(int c){//删除指定列
		node *t,*tt;
		//列结点左右被跳过
		col[c].right->left=col[c].left;
		col[c].left->right=col[c].right;
		//访问该列所有结点
		for(t=col[c].down;t!=&col[c];t=t->down){
			for(tt=t->right;tt!=t;tt=tt->right){
				//该列的结点数减少一个
				cnt[tt->c]--;
				//该行所有结点上下被跳过
				tt->up->down=tt->down;
				tt->down->up=tt->up;
			}
			
		}
	}
	void resume(int c){//恢复指定列
		node *t,*tt;
		for(t=col[c].down;t!=&col[c];t=t->down){
			//恢复结点
			t->right->left=t;
			t->left->right=t;
			for(tt=t->left;tt!=t;tt=tt->left){
				cnt[tt->c]++;
				tt->up->down=tt;
				tt->down->up=tt;
			}
		}
		col[c].left->right=&col[c];
		col[c].right->left=&col[c];
	}
	void solve(int k){
		if(head.right==&head){
			if(!scnt){
				memcpy(mem2,mem1,sizeof(mem1));
				mem=mem2;
			}
			scnt++;
			return;
		}
		node *t,*tt;
		int min=INF,tc;
		for(t=head.right;t!=&head;t=t->right){
			if(cnt[t->c]c];
				tc=t->c;
				if(min<=1)break;
			}
		}
		//移除这一列
		remove(tc);
		for(t=col[tc].down;t!=&col[tc];t=t->down){
			mem[k]=t->r;

			t->left->right=t;
			for(tt=t->right;tt!=t;tt=tt->right){
				remove(tt->c);
			}
			t->left->right=t->right;
			solve(k+1);
			
			if(scnt>=2)return;

			t->right->left=t;
			for(tt=t->left;tt!=t;tt=tt->left){
				resume(tt->c);
			}
			t->right->left=t->left;
		}
		resume(tc);
		return;
	}
	int* ReturnResult(){
		if(scnt>=1){
			return mem1;
		}
		else return NULL;
	}
};

class Range{
public:
	int i_Start;
	int i_End;
	int j_Start;
	int j_End;
	Range(){}
	void assign(int iS,int iE,int jS,int jE){
		i_Start=iS;
		i_End=iE;
		j_Start=jS;
		j_End=jE;
	}
	bool i_check(int i){
		return (i>=i_Start && i<=i_End);
	}
	bool j_check(int j){
		return (j>=j_Start && j<=j_End);
	}
	bool check(int i,int j){
		return (i_check(i) && j_check(j));
	}
};
/*
class Node{
public:
	bool a[10];
	bool Locked;
	Node(){
		int i=-1;
		for(;++i<10;){
			a[i]=true;
		}
		Locked=false;
	}
	bool OnlyOne(){
		int i=0,sum=0;
		for(;++i<10;){
			sum+=(int)a[i];
		}
		if(sum==1)return true;
		return false;
	}
	int Result(){
		int i=0;
		for(;++i<10;){
			if(a[i]==true){
				return i;
			}
		}
	}
	void setFalse(int i){
		a[i]=false;
	}
};
*/
DealWithSudoku DWS;

class sudoku{
private:
	int a[9][9];
	bool V[9][9];
	Range R[9];	
	int BelongTo_Check(int i,int j){
		int k=-1;
		for(;++k<9;){
			if(R[k].check(i,j)){
				return k;
			}
		}
		return -1;
	}
	bool Area_check(int iS,int iE,int jS,int jE){
		int i,j,n=0,sum;
		int s[9];
		for(i=iS-1;++i<=iE;){
			for(j=jS-1;++j<=jE;){
				if(a[i][j]!=0){
					s[n++]=a[i][j];
				}//if
			}//for
		}//for
		for(i=-1;++i'9'){
					break;
				}//if
			}//for
		}//for
		for(i=-1;++i<81;){
			if((int)(c[i]-'0')){
				V[i/9][i%9]=true;
			}
			a[i/9][i%9]=(int)(c[i]-'0');
		}//for
	}
	bool All_Check(){
		int i,j,k=-1,temp;
		for(;++k<9;){
			if(Area_check(R[k].i_Start,R[k].i_End,R[k].j_Start,R[k].j_End)){
				return false;
			}//if
		}//for
		for(i=-1;++i<9;){
			for(j=-1;++j<9;){
				for(temp=i;++temp<9;){
					if(a[temp][j]==a[i][j]){
						return false;
					}
				}
				for(temp=j;++temp<9;){
					if(a[i][temp]==a[i][j]){
						return false;
					}
				}
			}//for
		}//for
		return true;
	}
	bool Row_Check(int r){
		int i=-1,j;
		for(;++i<9;){
			for(j=i;++j<9;){
				if(a[r][i]==a[r][j]){
					return false;
				}
			}
		}
		return true;
	}
	bool Col_Check(int c){
		int i=-1,j;
		for(;++i<9;){
			for(j=i;++j<9;){
				if(a[i][c]==a[j][c]){
					return false;
				}
			}
		}
		return true;
	}
	sudoku(){
		srand((unsigned int)time(0));

		R[0].assign(0,2,0,2);
		R[1].assign(0,2,3,5);
		R[2].assign(0,2,6,8);
		R[3].assign(3,5,0,2);
		R[4].assign(3,5,3,5);
		R[5].assign(3,5,6,8);
		R[6].assign(6,8,0,2);
		R[7].assign(6,8,3,5);
		R[8].assign(6,8,6,8);

		int i=-1,j,R_N;
		for(;++i<9;){
			for(j=-1;++j<9;){
				a[i][j]=0;
				V[i][j]=false;
			}//for
		}//for
		int sum=rand()%40,temp;
		for(;sum--!=0;){
			i=rand()%9;
			j=rand()%9;
			R_N=BelongTo_Check(i,j);
			do{
				a[i][j]=rand()%10;
				for(temp=-1;++temp<9;){
					if(temp!=i){
						if(a[temp][j]==a[i][j]){
							a[i][j]=rand()%10;
							temp=-1;
						}//if
					}//if
         	  	    if(temp!=j){
						if(a[i][temp]==a[i][j]){
							a[i][j]=rand()%10;
							temp=-1;
						}//if
					}//if
				}//for	
			}//do
			while(Area_check(R[R_N].i_Start,R[R_N].i_End,R[R_N].j_Start,R[R_N].j_End));
			V[i][j]=true;
		}//for
	}//sudoku



	void display(){
		cout<<' '<<' ';
		int i=-1,j,k;
		//━┃
		cout<>i>>j>>n;
		if(i>=0 && i<=8 && j>=0 && j<=8 && n>=0 && n<=9 && !V[i][j]){
			a[i][j]=n;
			return false;
		}//if
		else if(i==11 && j==11 && n==11){
			if(All_Check()){
				return true;
			}
		}
		else if(i==12 && j==12 && n==12){
			DWS.setCh(a);
			int *s=DWS.ReturnResult();
			if(s){
				i=-1,j,n=1;
				int t,val;
				for(;++i<9;){
					for(j=-1;++j<9;){
						t=s[n]/9%81;
						val=s[n++]%9+1;
						a[t/9][t%9]=val;
					}
				}
			}
			return false;
		}
		else if(i==13 && j==13 && n==13){
			setFalse();
			DWS.initial();
			int i=-1,j,R_N;
			for(;++i<9;){
				for(j=-1;++j<9;){
					a[i][j]=0;
					V[i][j]=false;
				}//for
			}//for
			int sum=rand()%40,temp;
			for(;sum--!=0;){
				i=rand()%9;
				j=rand()%9;
				R_N=BelongTo_Check(i,j);
				do{
					a[i][j]=rand()%10;
					for(temp=-1;++temp<9;){
				    	if(temp!=i){
					    	if(a[temp][j]==a[i][j]){
					     		a[i][j]=rand()%10;
					    		temp=-1;
							}//if
						}//if
         	  	        if(temp!=j){
				    		if(a[i][temp]==a[i][j]){
					    		a[i][j]=rand()%10;
					    		temp=-1;
							}//if
						}//if
					}//for	
				}//do
		    	while(Area_check(R[R_N].i_Start,R[R_N].i_End,R[R_N].j_Start,R[R_N].j_End));
		    	V[i][j]=true;
			}//for
		}//else
		else{
			cout<<"Error!"<>c;
	switch(c){
	case 2:system("cls");SDK.Input();break;
	}
	system("cls");
	for(;;){
		SDK.display();
		if(SDK.assign()){
			cout<<"Win!"<


ConsoleColor.h 如下


#pragma once
#include 

#include 


inline std::ostream& blue(std::ostream &s)
{
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
    SetConsoleTextAttribute(hStdout, FOREGROUND_BLUE
              |FOREGROUND_GREEN|FOREGROUND_INTENSITY);
    return s;
}

inline std::ostream& red(std::ostream &s)
{
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
    SetConsoleTextAttribute(hStdout, 
                FOREGROUND_RED|FOREGROUND_INTENSITY);
    return s;
}

inline std::ostream& green(std::ostream &s)
{
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
    SetConsoleTextAttribute(hStdout, 
              FOREGROUND_GREEN|FOREGROUND_INTENSITY);
    return s;
}

inline std::ostream& yellow(std::ostream &s)
{
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
    SetConsoleTextAttribute(hStdout, 
         FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);
    return s;
}


inline std::ostream& white(std::ostream &s)
{
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
    SetConsoleTextAttribute(hStdout, 
       FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
    return s;
}

struct color {
    color(WORD attribute):m_color(attribute){};
    WORD m_color;
};

template 
std::basic_ostream<_Elem,_Traits>& 
      operator<<(std::basic_ostream<_Elem,_Traits>& i, color& c)
{
    HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE); 
    SetConsoleTextAttribute(hStdout,c.m_color);
    return i;
}

// Copyleft Vincent Godin


你可能感兴趣的:(C语言)