Other brush questions

Question of a written test:

Sawtooth Sudoku 3x3

Simply put, it is to give you a Sudoku filled with certain characters, telling you which 3 points belong to a palace, and then there can be no repetition in the same row and the same palace.

Next, given several sets of data, determine whether there is a solution. If there is a unique solution, output Unique and the solution. If there are multiple solutions, output Mutiple. If there is no solution, output no solution.

Ideas:

Classic matrix type, dfs traversal way. I encountered a few problems when I wrote it myself, and now I will summarize it here.

3 rows and 3 columns represent Sudoku information, and the following 3 rows represent three points of a palace.

The input data is as follows:

4
*2*
1*2
***
0 0 0 1 1 0
0 2 1 1 1 2
2 0 2 1 2 2

Traversal method: use dfs to traverse, then traverse up, down, left and right,

Returns if the point exceeds the bounds.

Return if visited. prevent revisiting.

There are two cases for the point, one is the point without assignment, then we assign the assignment, and judge from 1 to 3 in turn when assigning, to determine whether the point satisfies the row and rank without repetition.

If you have a point with a value, you don't need to visit it again, just return it directly .

(I thought so at first, and found that it can't be done : the reasons are as follows:

E.g:

When the point in the upper left corner is traversed by dfs, the points on the right and below have been assigned. If it is returned directly, it will appear that dfs cannot traverse the entire graph directly. Because the point (0, 0) is not connected to the outside world. So in order to achieve going out, do outgoing dfs even if the value is a little bit:

This ensures that the initial point (0, 0) of dfs must be able to traverse the entire graph.

 

The above is the case where there is a value for this point. Next, we introduce the case where there is no value for this point:

If there is no value, go to the interview from 1 to 3 in order to see if it is satisfied that the peers in the same column and the same palace do not have the same number, and fill in the first successful number.

After filling, it will checkNum++ (checkNum is the number of numbers that have been filled in the record). 

After finding a point, we will use this as a basis and continue to dfs: as shown in the red box in the following figure

When the dfs ends, that is, after backtracking, the value needs to be returned to its original state: as shown in the red box in the following figure

So how can you tell if a solution is found? What do I need to do after finding the solution?

The way to judge whether a solution is found is relatively simple. You only need to fill in the number and increase the checkNum to judge whether it is 9:

After finding the solution, add the value of ans to ++.

Since the solution needs to be output in the case of a single solution, and the filled numbers will be emptied during backtracking, we need to record the solution and use a successArray.

 

How to judge the idea of ​​multiple solutions here?

 

It is not necessary to find all the solutions here, it is only necessary to judge whether there are multiple solutions.

Therefore, if a solution is found, it is only necessary to record the solution, and then if the solution is found (that is, checkNum is 9), it is judged whether the two solutions are the same, and if they are not the same, there are multiple solutions.

code show as below:

#include<iostream>
using namespace std;
class Point {
public:
	int x, y;
	Point() {
	}
	Point(int x1, int y1) {
		x = x1, y = y1;
	}
};
class GongClass {
public:
	Point gongPoint[3];
};

class ShuDu {
	int array[3][3];
	bool visit[3][3];
	GongClass Gong[3];
	int checkNum = 0;//已经写完的数
	int successArray[3][3];
public:
	int hasAns = 0;
	void ShuDuInit() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				char num;
				cin >> num;
				if (num != '*') {
					checkNum++;
					array[i][j] = int(num - '0');
				}
				else array[i][j] = 0;
				visit[i][j]=false;
			}
		}

		for (int i = 0; i < 3; i++) {

			for (int k = 0; k < 3; k++) {
				int x, y;
				cin >> x >> y;
				Point point;
				point.x = x;
				point.y = y;
				Gong[i].gongPoint[k] = point;
			}

		}


		//dfsCheck(Point(0, 0));

		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				cout << "dfsPoint:" << i << " " << j << endl;
				printArray();
				dfsCheck(Point(i, j));
			}
		}
		/*cout << checkNum << endl;
		cout << hasAns << endl;*/
	}

	bool CheckRow(Point point, int num) {
		int x = point.x;
		int y = point.y;
		for (int j = 0; j < 3; j++) {
			if (array[x][j] == num) {
				//cout << "chongfuRow" << x << " " << j << endl;
				return false;
			}
		}
		return true;
	}
	bool CheckCol(Point point, int num) {

		int x = point.x;
		int y = point.y;
		for (int i = 0; i < 3; i++) {
			if (array[i][y] == num) {
				//cout << "chongfuCol " << i << " " << y << endl;
				//cout << "array i y:"<<array[i][y] << endl;
				return false;
			}
		}
		return true;
	}

	bool CheckGong(Point point, int num) {
		GongClass pointInGong = findGong(point);
		for (int i = 0; i < 3; i++) {
			int x = pointInGong.gongPoint[i].x;
			int y = pointInGong.gongPoint[i].y;
			if (array[x][y] == num)return false;
		}
		return true;
	}

	GongClass findGong(Point point) {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				if (Gong[i].gongPoint[j].x == point.x&&Gong[i].gongPoint[j].y == point.y)
					return Gong[i];
			}
		}

		return Gong[0];
	}

	void dfsCheck(Point point) {
		int x = point.x;
		int y = point.y;
		if (point.x < 0 || point.x >= 3 || point.y < 0 || point.y >= 3)return;
		if (visit[x][y] == true)return;

		/*if (visit[x+1][y] == false)dfsCheck(Point(x + 1, y));
		if (visit[x][y+1] == false)dfsCheck(Point(x, y + 1));
		if (visit[x - 1][y] == false)dfsCheck(Point(x - 1, y));
		if (visit[x][y-1] == false)dfsCheck(Point(x, y - 1));*/

		//cout << "point.x:" << x << " point.y:" << y << endl;

		visit[x][y] = true;//进入一个点则设置访问

		bool checkFlag = false;//检查是否有满足的数字可以填入
		if (array[x][y] == 0) {
			for (int index = 1; index <= 3; index++) {
				//检查该数字是否满足每行每列每宫的要求
				if (CheckRow(point, index) && CheckCol(point, index) && CheckGong(point, index)) {
					array[point.x][point.y] = index;
					checkNum++;

					checkFlag = true;
					cout << "success Point [" << x << "][" << y << "]"<< ":" << index << endl;
					if (checkNum == 9) {
						hasAns++;
						if (hasAns > 1) {
							if (checkSameArray()) {
								cout << "SameArray" << endl;
								hasAns--;
								break;
							}
						}
						cout << "hasAns" << endl;

						//由于回溯时会删去visit的记录和做好标记的结点,所以需要删除值,但是因为需要打印,所以需要将该成功的值保存
						for (int i = 0; i < 3; i++) {
							for (int j = 0; j < 3; j++)
								successArray[i][j] = array[i][j];
						}
						printArray();


					}


					//dfsCheck(Point(x + 1, y));
					//dfsCheck(Point(x, y + 1));
					//dfsCheck(Point(x - 1, y));
					//dfsCheck(Point(x, y - 1));

					//array[point.x][point.y] = 0;
					//checkNum--;
					//visit[x][y] = false;
					break;

					
				}
			}
		}
		else {
			//visit[x][y] = true;
			dfsCheck(Point(x + 1, y));
			dfsCheck(Point(x, y + 1));
			dfsCheck(Point(x - 1, y));
			dfsCheck(Point(x, y - 1));
			return;
		}


		//如果里面不能填入数字,说明前一步有问题,因此应该要返回,并且重置访问
		if (checkFlag == false) {
			visit[x][y] = false;
			return;
		
		}


		dfsCheck(Point(x + 1, y));
		dfsCheck(Point(x, y + 1));
		dfsCheck(Point(x - 1, y));
		dfsCheck(Point(x, y - 1));

		array[point.x][point.y] = 0;
		checkNum--;
		visit[x][y] = false;


		return;
	}

	void printSuccessArray() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				cout << successArray[i][j];
			}
			cout << endl;
		}
	}

	void printArray() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				cout << array[i][j];
			}
			cout << endl;
		}
	}

	bool checkSameArray() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				if (array[i][j] != successArray[i][j])return false;
			}
		}
		return true;
	}

};


int main() {

	int t;
	cin >> t;
	while (t--) {
		ShuDu shuDu;
		shuDu.ShuDuInit();
		if (shuDu.hasAns == 1) {
			cout << "Unique" << endl;
			shuDu.printSuccessArray();
		}
		else if(shuDu.hasAns>1){
			cout << "Multiple" << endl;
		}
		else cout << "NO"<<endl;
	}
};

	

/*

1
*2*
1*2
***
0 0 0 1 1 0
0 2 1 1 1 2
2 0 2 1 2 2


4
*2*
1*2
***
0 0 0 1 1 0
0 2 1 1 1 2
2 0 2 1 2 2
**3
***
***
0 0 1 0 1 1
0 1 0 2 1 2
2 0 2 1 2 2
**3
1**
**2
0 0 1 0 1 1
0 1 0 2 1 2
2 0 2 1 2 2
3*3
1**
**2
0 0 1 0 1 1
0 1 0 2 1 2
2 0 2 1 2 2


*/

 

Guess you like

Origin blog.csdn.net/weixin_43757333/article/details/123570128