【DFS】Ybt_数独游戏

题目大意

给你一些数独题,让你填。
空位以 ‘.’ 表示,多组数据,以end结尾。


深度搜索,剪枝。
用二进制位压缩储存状态,用这个以判断当前位置可以填的数字。


代码

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

int l[20], h[20], z[5][5], k[20][20], flag;
char c;

char getc(){  //输入
	char lc = getchar();
	while(( lc>'9' || lc<'0' ) && lc != '.' && lc != 'e') lc = getchar();
	return lc;
}

void init(){  //输入
	memset(l, 0, sizeof(l));
	memset(h, 0, sizeof(h));
	memset(z, 0, sizeof(z));
	for(int i = 1; i <= 9; ++i){
		for(int j = 1; j <= 9; ++j){
	  		if(c != '.'){
	  			k[i][j] = c-48;
	  			l[j] += 1 << (c-48-1);  //列,这个数的状态为1(填过)
	  			h[i] += 1 << (c-48-1);  //行,这个数的状态为1(填过)
	  			z[(i+2)/3][(j+2)/3] += 1 << (c-48-1); //小矩阵,这个数的状态为1(填过)
			}
			else k[i][j] = 0;
			c = getc();
	    }
	}   
}

void printt(){  //输出
	for(int i = 1; i <= 9; ++i)
	    for(int j = 1; j <= 9; ++j)
	  		printf("%d", k[i][j]);
	printf("\n");
}

void dfs(int bh){
	if(bh > 81){  //找到答案
		flag = 1;
		printt();
		return;
	}
	int x = (bh+8) / 9, y = (bh-1) % 9 + 1;  //当前点坐标
	int jzx = (x+2) / 3, jzy = (y+2) / 3;  //小矩阵是哪一个
	if(k[x][y] != 0) dfs(bh + 1);  //如果它本来就给出了这个数
	else for(int i = 1; i <= 9; ++i){  //枚举
		if((h[x] >> (i-1)) % 2 == 0)  //行没出现
		if((l[y] >> (i-1)) % 2 == 0)  //列没出现
		if((z[jzx][jzy] >> (i-1)) % 2 == 0){  //小矩阵没出现
	  		h[x] += 1 << (i-1);  //改变状态
			l[y] += 1 << (i-1);
	  		z[jzx][jzy] += 1 << (i-1);
	  		k[x][y] = i;  //记录答案
	  		dfs(bh+1);
	  		k[x][y] = 0;
	  		if(flag == 1) return;
	  		h[x] -= 1 << (i-1);
			l[y] -= 1 << (i-1);
	  		z[jzx][jzy] -= 1 << (i-1);
		}
	}
}

int main(){
	c = getc();
	while(c!='e'){  //多组数据
	 	init();
	 	flag = 0;
	 	dfs(1);
	}
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值