POJ2676

填数独。

直接暴力深搜,哪个点要填就不断的填下去,每填一个就判断该格填的数满不满足要求,满足要求了就搜下去,搜到最深处直接输出就OK了。

不过时间复杂度有点高。没什么剪枝和优化。

#include <iostream>
#include <cstring>
using namespace std;
const int MAX = 10;
int su_do_ku[MAX][MAX], to_fill[MAX*MAX];
int to_fill_number;
int has_find;
void dfs(int row,int column,int cur) {
	if (cur == to_fill_number){
		has_find = 1;
		for (int i = 1; i < MAX; i++) {
			for (int j = 1; j < MAX; j++){
				cout << su_do_ku[i][j];
			}
			cout << endl;
		}
		return ;
	} else {
		for (int i = 1; i < 10; i++) {
			if(has_find)
				return ;
			int ok =1;
			int flag = 0;
			for (int j = 1; j < 10; j++) {
				if (su_do_ku[row][j] == i ) {
					ok = 0;
					flag = 1;
					break;
				}
				if (su_do_ku[j][column] == i) {
					ok = 0;
					flag = 1;
					break;
				}
			}
			if (flag) 
				continue;
			int box_row = (row - 1)/3;
			int box_column = (column - 1) / 3;
			for (int k = box_row * 3 + 1; k <= box_row * 3 + 3 && !flag; k++) {
				for (int m = box_column * 3 + 1; m <= box_column * 3 + 3; m++) {
					if(su_do_ku[k][m] == i){
						ok = 0;
						flag = 1;
						break;
					}
				}
			}
			if (ok) {
				su_do_ku[row][column] = i;
				dfs(to_fill[cur+1]/10,to_fill[cur+1]%10,cur+1);
				su_do_ku[row][column] = 0;
			}
		}
	}
}
int main()
{
	int test_case;
	cin >> test_case;
	cin.get();
	while (test_case--) {
		memset(su_do_ku,0,sizeof(su_do_ku));
		memset(to_fill,0,sizeof(to_fill));
		to_fill_number = 0;
		for (int i = 1; i < MAX; i++) {
			for (int j = 1; j < MAX; j++){
				char ch;
				cin.get(ch);
				su_do_ku[i][j] = ch - '0';
				if (su_do_ku[i][j] == 0) {
					to_fill[to_fill_number] = i*10 + j;
					to_fill_number++;
				}
			}
			cin.get();
		}
		has_find = 0;
		dfs(to_fill[0]/10,to_fill[0]%10,0);
	}
	return 0;
}


你可能感兴趣的:(POJ2676)