用舞蹈链实现数独2

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

输入13 13 13更换数独开局

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

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

#include<iostream>
#include<stdio.h>
#include<stdlib.h>//rand函数
#include<time.h>//srand函数
#include"ConsoleColor.h"
#include<conio.h>
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(;++i<CC;){
			col[i].c=i;
			col[i].r=RR;
			col[i].up=&col[i];
			col[i].down=&col[i];

			col[i].left=&head;
			col[i].right=head.right;

			col[i].left->right=&col[i];
			col[i].right->left=&col[i];
		}//for
		//建立行
		for(i=-1;++i<RR;){
			row[i].r=i;
			row[i].c=CC;
			row[i].left=&row[i];
			row[i].right=&row[i];


			row[i].up=&head;
			row[i].down=head.down;
			row[i].up->down=&row[i];
			row[i].down->up=&row[i];
		}//for
		int r,c,val,tr,tc;
		for(i=-1;++i<RR;){
			r=i/9/9%9;
			c=i/9%9;
			val=i%9+1;
			if(ch[r*9+c]==0 || ch[r*9+c]==val){
				link(i,r*9+val-1);
				link(i,81+c*9+val-1);
				tr=r/3;
				tc=c/3;
				link(i,162+(tr*3+tc)*9+val-1);
				link(i,243+r*9+c);
			}//if
		}//for
		for(i=-1;++i<RR;){
			row[i].left->right=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->rig
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值