输入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