【DFS】 poj2676 数独

题目描述:给一个数独,0代表空,解这个数独,有解输出这个解,无解输出原格式

思路:

数独每行每列每块小区域的1-9都是不能重复的
那就设置三个bool来判重
列判重 col[10][10] 行判重 row[10][10] 区域判重 grid[10][10]
列和行判重比较简单,改变前面的那个数字就行,区域判重就要判断输入的那个坐标点是在哪个地方。

这边又新的更新,有一天在洛谷上碰到数独时突想的歪门邪道
int find(int x, int y) {
	if ( x>=1 && x<=3 ) {
		if ( y>=1 && y<=3 ) return 1;
		else if ( y>=4 && y<=6 ) return 2;
		else if ( y>=7 && y<=9 ) return 3;
	}
	else if ( x>=4 && x<=6 ) {
		if ( y>=1 && y<=3 ) return 4;
		else if ( y>=4 && y<=6 ) return 5;
		else if ( y>=7 && y<=9 ) return 6;
	}
	else if ( x>=7 && x<=9 ) {
		if ( y>=1 && y<=3 ) return 7;
		else if ( y>=4 && y<=6 ) return 8;
		else if ( y>=7 && y<=9 ) return 9;
	}
}
我定一个find函数每次去查找不就行了,哈哈哈
接下来是推算的方法:

每一个点所在的小区域都是3x3形式的,所以我们可以发现行坐标决定的是这个点在哪一行大区域,比如说行号为1,2,3的,他们的区域一定在第一行,行4,5,6,他们的区域一定在第二大行。列坐标一样可以决定这个点在哪个列的大区域,1,2,3列在第一列大区域,4,5,6在第二列大区域。这样就可以计算这个坐标点在哪个区域了。
1,2,3行的属于(1,3)区域,4,5,6行属于(4,6)区域。
可以看作是0+所在列的区域和3+所在列的区域。
列的区域就很好算了,下面直接给公式
i为行坐标,j为列坐标,区域k= ( i - 1 ) / 3 * 3+ ( j - 1 ) / 3 + 1 ;
千万不要k=i / 4 * 3+j / 4 + 1; 因为第7行和第7列会出错。
这个问题解决了那就愉快的dfs了

我用G++跑 ce了,用C++跑ac,咱也不知道为撒

贴代码

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;

char s[10][10];     //输入
int map[10][10];         //转化为字符用
bool row[10][10],col[10][10],grid[10][10];

bool dfs(int x, int y) {
	bool flag=false;
	if ( x==10 ) return true;
	
	// 分两种情况,一种是有数字,一种是没数字的情况,这里是有数字
	if ( map[x][y] ) {
		if ( y==9 ) flag=dfs(x+1,1);
		else flag=dfs(x,y+1);
		if ( flag ) return true;
		else return false;
	}

	//每数字的情况
	for(int i=1; i<=9; i++ ) {
		int k=3*((x-1)/3)+(y-1)/3+1;
		if ( !row[x][i] && !col[y][i] && !grid[k][i] ) {
			map[x][y]=i;
			row[x][i]=col[y][i]=grid[k][i]=1;
			if ( y==9 ) flag=dfs(x+1,1);
			else flag=dfs(x,y+1);
			if ( flag ) return true;
			else {
				map[x][y]=row[x][i]=col[y][i]=grid[k][i]=0;
			}
		}
	}
	return false;
}

int main()
{
	int t;
	cin>>t;
	while(t--) {
		memset(row,0,sizeof(row));
		memset(col,0,sizeof(col));
		memset(grid,0,sizeof(grid));
		//处理
		for(int i=1; i<=9; i++ ) {
			for(int j=1; j<=9; j++ ) {
				cin>>s[i][j];
				map[i][j]=s[i][j]-'0';
				if ( map[i][j] ) {
					int k=3*((i-1)/3)+(j-1)/3+1;
					row[i][map[i][j]]=1;
					col[j][map[i][j]]=1;
					grid[k][map[i][j]]=1;
				}
			}
		}
		dfs(1,1);
		for(int i=1; i<=9; i++ ) {
			for(int j=1; j<=9; j++ ) {
				cout<<map[i][j];
			}
			cout<<endl;
		}
	}
	return 0;
}
发布了13 篇原创文章 · 获赞 6 · 访问量 584

猜你喜欢

转载自blog.csdn.net/zx1020354953/article/details/104038074