【ybt高效进阶1-4-2】【luogu P1784】数独游戏 /数独

数独游戏 / 数独

题目链接:luogu P1784 / ybt高效进阶1-4-2

题目大意

就是给你一个数独,要你填完它。

思路

这道题其实就是爆搜。

你就直接一个位置一个位置的看,然后每个位置 1 ∼ 9 1\sim 9 19 看放哪个数。
要能放这个数,要有几个条件:

  1. 这个数没有一开始就填好
  2. 它不跟它这一行的某个数相同,弄一个变量记录某一行有那些数就可以了
  3. 它不跟它这一列的某个数相同,弄一个变量记录某一列有那些数就可以了
  4. 它不跟它这个区块的某个数相同,也弄一个变量记录。

下面的图片中,同一个颜色的就是一个区块:
在这里插入图片描述

也就是说这个:
在这里插入图片描述
这是一个格子对应的不能跟它一样的格子。
(粉色代表同一行,黄色代表同一列,蓝色就是同一区块)

那我们就按照上面的条件爆搜,就可以得出答案。
时间是可以的,不会超时,一找到就整个退出就可以不超时了。

代码

luogu P1784

#include<cstdio>
#include<cstring>

using namespace std;

bool block[11][11], heng[11][11], zong[11][11], yes;
int a[11][11];

void write() {
	for (int i = 1; i <= 9; i++) {
		for (int j = 1; j <= 9; j++)
			printf("%d ", a[i][j]);
		printf("\n");
	}
	
	return ;
}

int get_block(int x, int y) {
	if (x <= 3) return 1 + (y - 1) / 3;
		else if (x <= 6) return 4 + (y - 1) / 3;
			else return 7 + (y - 1) / 3;
}

void dfs(int x, int y) {
	if (y > 9) {
		y = 1;
		x++;
	}
	
	if (x == 10 && y == 1) {
		write();
		yes = 1;
		return ;
	}
	
	if (a[x][y] != -1) {
		dfs(x, y + 1);
		
		return ;
	}
	
	for (int i = 1; i <= 9; i++) {
		if (!block[get_block(x, y)][i] && !heng[x][i] && !zong[y][i]) {
			block[get_block(x, y)][i] = 1;
			heng[x][i] = 1;
			zong[y][i] = 1;
			a[x][y] = i;
			
			dfs(x, y + 1);
			if (yes) return ;
			
			block[get_block(x, y)][i] = 0;
			heng[x][i] = 0;
			zong[y][i] = 0;
			a[x][y] = -1;
		}
	}
	
	return ;
}

int main() {
	for (int i = 1; i <= 9; i++)
		for (int j = 1; j <= 9; j++) {
			scanf("%d", &a[i][j]);
			if (a[i][j]) {
				block[get_block(i, j)][a[i][j]] = 1;
				heng[i][a[i][j]] = 1;
				zong[j][a[i][j]] = 1;
			}
			else a[i][j] = -1;
		}
	
	dfs(1, 1);
		
	return 0;
}

ybt高效进阶1-4-2

#include<cstdio>
#include<cstring>

using namespace std;

bool block[11][11], heng[11][11], zong[11][11], yes;
int a[11][11];
char c[91];

void write() {
	for (int i = 1; i <= 9; i++)
		for (int j = 1; j <= 9; j++)
			printf("%d", a[i][j]);
	printf("\n");
	
	return ;
}

int get_block(int x, int y) {
	if (x <= 3) return 1 + (y - 1) / 3;
		else if (x <= 6) return 4 + (y - 1) / 3;
			else return 7 + (y - 1) / 3;
}

void dfs(int x, int y) {
	if (y > 9) {
		y = 1;
		x++;
	}
	
	if (x == 10 && y == 1) {
		write();
		yes = 1;
		return ;
	}
	
	if (a[x][y] != -1) {
		dfs(x, y + 1);
		
		return ;
	}
	
	for (int i = 1; i <= 9; i++) {
		if (!block[get_block(x, y)][i] && !heng[x][i] && !zong[y][i]) {
			block[get_block(x, y)][i] = 1;
			heng[x][i] = 1;
			zong[y][i] = 1;
			a[x][y] = i;
			
			dfs(x, y + 1);
			if (yes) return ;
			
			block[get_block(x, y)][i] = 0;
			heng[x][i] = 0;
			zong[y][i] = 0;
			a[x][y] = -1;
		}
	}
	
	return ;
}

int main() {
	scanf("%s", &c);
	
	while (c[0] != 'e' || c[1] != 'n' || c[2] != 'd') {
		memset(block, 0, sizeof(block));
		memset(heng, 0, sizeof(heng));
		memset(zong, 0, sizeof(zong));
		yes = 0;
		
		for (int i = 0; i < 81; i++)
			if (c[i] != '.') {
				a[1 + (i) / 9][i % 9 + 1] = c[i] - '0';
				block[get_block(1 + (i) / 9, i % 9 + 1)][c[i] - '0'] = 1;
				heng[1 + (i) / 9][c[i] - '0'] = 1;
				zong[i % 9 + 1][c[i] - '0'] = 1;
			}
			else a[1 + (i) / 9][i % 9 + 1] = -1;
		
		dfs(1, 1);
		
		scanf("%s", &c);
	}
	
	return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值