• Dominosa/数邻(2) | C++ | BFS


    一、Dominosa简介

       Dominosa,中文名称为数邻,是一种棋盘游戏,基于骨牌的排列和匹配来进行。它是从骨牌游戏中发展而来的,在骨牌的基础上添加了一些规则和难度。具体的游戏规则是:将一副骨牌放置在一个棋盘上,玩家需要根据这些固定数字推断出正确的骨牌排列。

       Dominosa 是一款非常有趣和具有挑战性的游戏。我是在大三小学期的 Linux 实训中,在虚拟机上接触到了这个小游戏。由于我本身玩过骨牌,同时对这种类型的数学游戏也很感兴趣,它们实在是令我着迷。

       Dominosa 需要玩家运用逻辑思维和推理能力来解决问题。它的规则相对简单,但难度却很高,因为骨牌排列的可能性非常多。如果您喜欢逻辑游戏,并且想尝试一些挑战性的新游戏,那么 Dominosa 绝对值得一试!

       对于没有接触过骨牌的同学来说或许还不太能理解这个游戏,那么我们下面举一个具体的例子。下面是一个经典的 Dominosa 谜面。

    在这里插入图片描述

    答案如下:

    在这里插入图片描述

       可见,盘面上的数字被两两划分,且保证每个划分都互不重复。

       我相信看完例子你一定懂了这个游戏的规则!现在,请你编写一个程序,对于给定的 Dominosa 谜面,能够自动判断是否有解,如果有解,还能够给出一个正确的解。

    二、题目描述

    输入一个未解的 Dominosa 谜面,输出它的结果。
    Input
    由两部分输入组成。第一部分只有一个正整数n,表示最大数字,第二部分有n+1行,每行n+2个正整数,表示谜面。
    Output
    谜题的解,如果两个数字能够组成一个骨牌,那么将它们的位置标记为相同的数字。标记方法可能不唯一,但是标记必须容易辨认。

    测试用例1
    在这里插入图片描述

    测试用例2
    在这里插入图片描述
    输入(供复制):
    9
    82419008183
    64907897150
    03198511218
    68804535022
    37763052729
    74416693226
    36165567745
    81442980856
    42513904405
    93269977337

    三、编程思路

    在昨天的代码基础上,

    1. 将求解的步骤单独写成一个函数
    2. 当需要用到BFS的时候,可以递归调用这个求解函数
    3. 当找到正确解后,输出正确解,然后逐层返回,程序结束

    四、完整代码

    说明:代码中默认为输出到命令行中,我们也提供了输出到文件中的选项,只要在程序的第 390-395 行,更改被注释的内容即可。

    #include
    using namespace std;
    int N = 30;							// N: 最大数字,不难计算出盘面的行数=N+1,列数=N+2
    // 定义单格
    typedef struct {
    	int number = -1;						// 表示当前格内的数字,初始是-1
    	int con = 0;							// 表示当前格是否已建立连接,如果未连接,则为0,如果已连接,则为1
    	int up=1, down=1, left=1, right=1;		// 标记当前格的上、下、左、右格子是否可能建立连接,如果可能则为1,如果不能则为0
    	int sequ = 0;
    } Single;
    
    // 定义骨牌
    typedef struct {
    	int count;				// 编号:以6为例,00->0, 01->1, ..., 06->6, 11->7, ..., 16->12, 22->13, ..., 55->25, 56->26, 66->27;count是每种骨牌的数量
    	bool used;				// used是骨牌是否已经出现过,若已经出现过则为true
    } bridge;
    
    int addd(int m){			// 一个求和的函数
    	int s = 0;
    	for (int i=1; i<m; i++) s+=i;
    	return s;
    }
    // 根据骨牌上的两个数字将其转换为对应的b_id
    int trans_numbers_bid(int number1, int number2) {	
    	int addd(int);		
    	int less = number1 < number2 ? number1 : number2, more = number1 + number2 - less;
    	int b_id = less*N+more;
    	if (less>1) b_id-=addd(less);
    	return b_id;
    }
    
    // Dominosa棋盘类
    class Dominosa{
    public:
    	Dominosa(){};				// 构造函数
    	Dominosa(const Dominosa&);	// 拷贝函数
    	~Dominosa(){};				// 析构函数
    	Single lattice[31][32];		// 第i行第j列的格子位置为:k=21*i+j,支持的最大数字 N=30
    	bridge b[31*32/2];
    	void init_connect();		// 初始化所有格子的up、down、left、right
    	int sum_of_up_down_left_right(int m, int n); // 计算上下左右的和
    	int sequence = 1;
    };
    Dominosa:: Dominosa(const Dominosa& dd) {
    	for (int i=0; i<21; i++) {
    		for (int j=0; j<22; j++) {
    			this->lattice[i][j] = dd.lattice[i][j];
    		}
    	}
    	for (int i=0; i<(N+1)*(N+2)/2; i++) {
    		this->b[i].used = dd.b[i].used;
    	}
    	this -> sequence = dd.sequence;
    }
    void Dominosa:: init_connect(){
    	// 初始化所有格子的up、down、left、right
    	for (int j=0; j<N+2; j++) {
    		lattice[0][j].up = 0;
    		lattice[N][j].down = 0;
    	}
    	for (int i=0; i<N+1; i++) {
    		lattice[i][0].left = 0;
    		lattice[i][N+1].right = 0;
    	}
    	// 初始化 bridge
    	for (int i=0; i<(N+1)*(N+2)/2; i++) {
    		b[i].used = false;
    	}
    }
    // 计算当前格与上下左右可能性的和,m是行数,n是列数
    int Dominosa:: sum_of_up_down_left_right(int m, int n){
    	// 如果是边缘格子,单独考虑
    	if (m==0) {
    		if (n==0) {
    			return lattice[m][n].right+lattice[m][n].down;
    		}
    		else if (n==N+1) {
    			return lattice[m][n].left+lattice[m][n].down;
    		}
    		else {
    			return lattice[m][n].left+lattice[m][n].right+lattice[m][n].down;
    		}
    	}
    	else if (m==N) {
    		if (n==0) {
    			return lattice[m][n].up+lattice[m][n].right;
    		}
    		else if (n==N+1) {
    			return lattice[m][n].left+lattice[m][n].up;
    		}
    		else {
    			return lattice[m][n].left+lattice[m][n].right+lattice[m][n].up;
    		}
    	}
    	else {
    		if (n==0) {
    			return lattice[m][n].right+lattice[m][n].up+lattice[m][n].down;
    		}
    		else if (n==N+1) {
    			return lattice[m][n].left+lattice[m][n].up+lattice[m][n].down;
    		}
    		else {
    			return lattice[m][n].up+lattice[m][n].down+lattice[m][n].left+lattice[m][n].right;
    		}
    	}
    }
    
    // 求解 Dominosa 谜面,并调用print函数输出解
    int D_solve(Dominosa D) {		// 返回-1,表示无解;返回0,表示可能有解,但需要BFS进一步计算;返回1,表示成功解出。
    
    	void print_solution(Dominosa);
    	void print_solution_in_file(Dominosa);
    
    	int count_of_bridges = (N+1)*(N+2)/2;
    	bool update = true;
    	while (update) {
    		update = false;
    		
    		// 初始化bridge.count
    		for (int i=0; i<count_of_bridges; i++) {
    			D.b[i].count = 0;
    		}
    		// 全面扫描D,更新bridge.count
    		// 先横向扫描一遍,更新bridge.count
    		for (int i=0; i<N+1; i++) {
    			for (int j=0; j<N+1; j++) {
    				if (D.lattice[i][j].con==0 && D.lattice[i][j+1].con==0) {
    					D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].count++;
    				}
    			}
    		}
    		// 再纵向扫描一遍,更新bridge.count
    		for (int i=0; i<N; i++) {
    			for (int j=0; j<N+2; j++) {
    				if (D.lattice[i][j].con==0 && D.lattice[i+1][j].con==0) {
    					D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].count++;
    				}
    			}
    		}
    		// 全面扫描一遍,检查是否有四面都连接不了的格子,如果有,直接返回-1
    		for (int i=0; i<N+1; i++) {
    			for (int j=0; j<N+2; j++) {
    				if (D.lattice[i][j].con==0 && D.sum_of_up_down_left_right(i, j)==0) {
    					return -1;
    				}
    			}
    		}
    
    		// 从左向右扫描一遍,并尝试向右建立连接
    		for (int i=0; i<N+1; i++) {
    			for (int j=0; j<N+1; j++) {
    				if (D.lattice[i][j].con==0 && D.lattice[i][j+1].con==0) {
    					if (D.sum_of_up_down_left_right(i, j)==1 && D.lattice[i][j].right==1) {
    						D.lattice[i][j].con = 1;
    						D.lattice[i][j].sequ = D.sequence;
    						D.lattice[i][j+1].con = 1;
    						D.lattice[i][j+1].sequ = D.sequence;
    						D.sequence++;
    						D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].used = true;
    						update = true;
    					}
    					if (D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].used==false
    						&& D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].count==1) {
    							D.lattice[i][j].con = 1;
    							D.lattice[i][j].sequ = D.sequence;
    							D.lattice[i][j+1].con = 1;
    							D.lattice[i][j+1].sequ = D.sequence;
    							D.sequence++;
    							D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].used = true;
    							update = true;
    					}
    				}
    			}
    		}
    		// 从右向左扫描一遍,并尝试向左建立连接
    		for (int i=0; i<N+1; i++) {
    			for (int j=1; j<N+2; j++) {
    				if (D.lattice[i][j].con==0 && D.lattice[i][j-1].con==0) {
    					if (D.sum_of_up_down_left_right(i, j)==1 && D.lattice[i][j].left==1) {
    						D.lattice[i][j].con = 1;
    						D.lattice[i][j].sequ = D.sequence;
    						D.lattice[i][j-1].con = 1;
    						D.lattice[i][j-1].sequ = D.sequence;
    						D.sequence++;
    						D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j-1].number)].used = true;
    						update = true;
    					}
    					if (D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j-1].number)].used==false
    						&& D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j-1].number)].count==1) {
    							D.lattice[i][j].con = 1;
    							D.lattice[i][j].sequ = D.sequence;
    							D.lattice[i][j-1].con = 1;
    							D.lattice[i][j-1].sequ = D.sequence;
    							D.sequence++;
    							D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j-1].number)].used = true;
    							update = true;
    					}
    				}
    			}
    		}
    		// 从上向下扫描一遍,并尝试向下建立连接
    		for (int i=0; i<N; i++) {
    			for (int j=0; j<N+2; j++) {
    				if (D.lattice[i][j].con==0 && D.lattice[i+1][j].con==0) {
    					if (D.sum_of_up_down_left_right(i, j)==1 && D.lattice[i][j].down==1) {
    						D.lattice[i][j].con = 1;
    						D.lattice[i][j].sequ = D.sequence;
    						D.lattice[i+1][j].con = 1;
    						D.lattice[i+1][j].sequ = D.sequence;
    						D.sequence++;
    						D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].used = true;
    						update = true;
    					}
    					if (D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].used==false
    						&& D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].count==1) {
    							D.lattice[i][j].con = 1;
    							D.lattice[i][j].sequ = D.sequence;
    							D.lattice[i+1][j].con = 1;
    							D.lattice[i+1][j].sequ = D.sequence;
    							D.sequence++;
    							D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].used = true;
    							update = true;
    					}
    				}
    			}
    		}
    		// 从下向上扫描一遍,并尝试向上建立连接
    		for (int i=1; i<N+1; i++) {
    			for (int j=0; j<N+2; j++) {
    				if (D.lattice[i][j].con==0 && D.lattice[i-1][j].con==0) {
    					if (D.sum_of_up_down_left_right(i, j)==1 && D.lattice[i][j].up==1) {
    						D.lattice[i][j].con = 1;
    						D.lattice[i][j].sequ = D.sequence;
    						D.lattice[i-1][j].con = 1;
    						D.lattice[i-1][j].sequ = D.sequence;
    						D.sequence++;
    						D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i-1][j].number)].used = true;
    						update = true;
    					}
    					if (D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i-1][j].number)].used==false
    						&& D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i-1][j].number)].count==1) {
    							D.lattice[i][j].con = 1;
    							D.lattice[i][j].sequ = D.sequence;
    							D.lattice[i-1][j].con = 1;
    							D.lattice[i-1][j].sequ = D.sequence;
    							D.sequence++;
    							D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i-1][j].number)].used = true;
    							update = true;
    					}
    				}
    			}
    		}
    
    		// 全面更新D的每个con=0格子的up、down、left、right状态
    		// 如果相邻的格子的con=1,则将其方向设置为0
    		// 如果相邻的格子的con=0,但bridge.used=true,也要将其方向设置为0
    		{
    			int i=0;
    			{
    				int j=0;
    				if (D.lattice[i][j].con==0) {
    					if (D.lattice[i][j+1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].used==true ) {
    						D.lattice[i][j].right = 0;
    					}
    					if (D.lattice[i+1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].used==true ) {
    						D.lattice[i][j].down = 0;
    					}
    				}
    				for (j=1; j<N+1; j++) {
    					if (D.lattice[i][j].con==0) {
    						if (D.lattice[i][j-1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j-1].number)].used==true ) {
    							D.lattice[i][j].left = 0;
    						}
    						if (D.lattice[i][j+1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].used==true ) {
    							D.lattice[i][j].right = 0;
    						}
    						if (D.lattice[i+1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].used==true ) {
    							D.lattice[i][j].down = 0;
    						}
    					}
    				}
    				j = N+1;
    				if (D.lattice[i][j].con==0) {
    					if (D.lattice[i][j-1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j-1].number)].used==true ) {
    						D.lattice[i][j].left = 0;
    					}
    					if (D.lattice[i+1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].used==true ) {
    						D.lattice[i][j].down = 0;
    					}
    				}
    			}
    
    			{
    				for (i=1; i<N; i++) {
    					int j=0;
    					if (D.lattice[i][j].con==0) {
    						if (D.lattice[i][j+1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].used==true ) {
    							D.lattice[i][j].right = 0;
    						}
    						if (D.lattice[i-1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i-1][j].number)].used==true ) {
    							D.lattice[i][j].up = 0;
    						}
    						if (D.lattice[i+1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].used==true ) {
    							D.lattice[i][j].down = 0;
    						}
    					}
    					for (j=1; j<N+1; j++) {
    						if (D.lattice[i][j].con==0) {
    							if (D.lattice[i][j-1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j-1].number)].used==true ) {
    								D.lattice[i][j].left = 0;
    							}
    							if (D.lattice[i][j+1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].used==true ) {
    								D.lattice[i][j].right = 0;
    							}
    							if (D.lattice[i-1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i-1][j].number)].used==true ) {
    								D.lattice[i][j].up = 0;
    							}
    							if (D.lattice[i+1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].used==true ) {
    								D.lattice[i][j].down = 0;
    							}
    						}
    					}
    					j = N+1;
    					if (D.lattice[i][j].con==0) {
    						if (D.lattice[i][j-1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j-1].number)].used==true ) {
    							D.lattice[i][j].left = 0;
    						}
    						if (D.lattice[i-1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i-1][j].number)].used==true ) {
    							D.lattice[i][j].up = 0;
    						}
    						if (D.lattice[i+1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i+1][j].number)].used==true ) {
    							D.lattice[i][j].down = 0;
    						}
    					}
    				}
    			}
    
    			{
    				i = N;
    				int j=0;
    				if (D.lattice[i][j].con==0) {
    					if (D.lattice[i][j+1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].used==true ) {
    						D.lattice[i][j].right = 0;
    					}
    					if (D.lattice[i-1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i-1][j].number)].used==true ) {
    						D.lattice[i][j].up = 0;
    					}
    				}
    				for (j=1; j<N+1; j++) {
    					if (D.lattice[i][j].con==0) {
    						if (D.lattice[i][j-1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j-1].number)].used==true ) {
    							D.lattice[i][j].left = 0;
    						}
    						if (D.lattice[i][j+1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j+1].number)].used==true ) {
    							D.lattice[i][j].right = 0;
    						}
    						if (D.lattice[i-1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i-1][j].number)].used==true ) {
    							D.lattice[i][j].up = 0;
    						}
    					}
    				}
    				j = N+1;
    				if (D.lattice[i][j].con==0) {
    					if (D.lattice[i][j-1].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i][j-1].number)].used==true ) {
    						D.lattice[i][j].left = 0;
    					}
    					if (D.lattice[i-1][j].con==1 || D.b[trans_numbers_bid(D.lattice[i][j].number, D.lattice[i-1][j].number)].used==true ) {
    						D.lattice[i][j].up = 0;
    					}
    				}
    			}
    		}
    	}
    
    	int fbi=-1, fbj=-1;
    	// 检测是否已经成功解出,如果未解出,标记第一个未连接的格子
    	bool if_solve = true;
    	for (int i=0; i<N+1; i++) {
    		for (int j=0; j<N+2; j++) {
    			if (D.lattice[i][j].con==0) {
    				fbi = i;
    				fbj = j;
    				if_solve = false;
    				break;
    			}
    		}
    		if (if_solve==false) break;
    	}
    
    	// 如果已经解出,则返回true
    	if (if_solve==true) {
    		print_solution(D);	// 输出到命令行中
    		// print_solution_in_file(D);	// 输出到文件 output.txt 中
    		return 1;
    	}
    	
    	// 否则用BFS求解(其实用的是递归啦哈哈)
    	Dominosa d1(D), d2(D);
    	// 设置d1为向右连接
    	d1.lattice[fbi][fbj  ].con = 1;	d1.lattice[fbi][fbj  ].sequ = d1.sequence;
    	d1.lattice[fbi][fbj+1].con = 1;	d1.lattice[fbi][fbj+1].sequ = d1.sequence;
    	d1.sequence++;
    	d1.b[trans_numbers_bid(d1.lattice[fbi][fbj].number, d1.lattice[fbi][fbj+1].number)].used = true;
    	int solve_d1 = D_solve(d1);
    	if (solve_d1==1) {
    		return 1;
    	}
    
    	// 设置d2为向下连接
    	d2.lattice[fbi  ][fbj].con = 1; d2.lattice[fbi  ][fbj].sequ = d2.sequence;
    	d2.lattice[fbi+1][fbj].con = 1; d2.lattice[fbi+1][fbj].sequ = d2.sequence;
    	d2.sequence++;
    	d2.b[trans_numbers_bid(d2.lattice[fbi][fbj].number, d2.lattice[fbi+1][fbj].number)].used = true;
    	int solve_d2 = D_solve(d2);
    	if (solve_d2==1) {
    		return 1;
    	}
    
    	return 0;
    }
    
    // 在命令行中输出最终的结果
    void print_solution(Dominosa D) {
    	for (int i=0; i<N+1; i++) {
    		for (int j=0; j<N+2; j++) {
    			cout << setw(4) << D.lattice[i][j].sequ;
    		}
    		cout << endl;
    	}
    }
    
    // 将结果输出到 output.txt 中
    void print_solution_in_file(Dominosa D) {
    	fstream f;
    	f.open("output.txt", ios::out|ios::app);
    	f << endl; // 如果output.txt中本身已经有内容了,可以将其区分开,避免混淆
    
    	for (int i=0; i<N+1; i++) {
    		for (int j=0; j<N+2; j++) {
    			f << setw(4) << D.lattice[i][j].sequ;
    		}
    		f << endl;
    	}
    	f.close();
    }
    
    Dominosa DMNS;				// 基础盘面DMNS
    int main() {
    	
    	int trans_numbers_bid(int, int);
    	int D_solve(Dominosa);
    
    	// 初始化谜面
    	DMNS.init_connect();
    
        freopen("input.txt","r",stdin);		// 谜面放在 input.txt 中
        //读入待解盘面D
    	scanf("%d\n", &N);
    	char c;
    	for (int i=0; i<N+1; i++) {
    		for (int j=0; j<N+2; j++) {
    			scanf("%c", &c);
    			DMNS.lattice[i][j].number = c - '0';
    			DMNS.lattice[i][j].con = 0;
    		}
    		scanf("%*c");
    	}
    	
    	int r = D_solve(DMNS);
    	
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473

    现在的代码应该能够做到求解出每一个 Dominosa 谜题的答案,当然,你得确保谜题本身有解。

  • 相关阅读:
    花书——PyTorch版本
    U++ 游戏类 学习笔记
    MongoDB自学笔记(一)
    java毕业设计创新创业教育中心项目申报管理系统Mybatis+系统+数据库+调试部署
    各位程序员们,睡眠不足产生的后果超出你想象!
    新生儿低烧:原因、科普和注意事项
    顾往前行,我的前端之路系列(三)
    职场沟通技巧
    Hive-启动与操作(2)
    使用Selenium进行Web自动化操作
  • 原文地址:https://blog.csdn.net/m0_70241024/article/details/132757882