AcWing166.数独(dfs+剪枝)

题目:https://www.acwing.com/problem/content/168/

数独是一种传统益智游戏,你需要把一个9 × 9的数独补充完整,使得图中每行、每列、每个3 × 3的九宫格内数字1~9均恰好出现一次。

请编写一个程序填写数独。

输入格式

输入包含多组测试用例。

每个测试用例占一行,包含81个字符,代表数独的81个格内数据(顺序总体由上到下,同行由左到右)。

每个字符都是一个数字(1-9)或一个”.”(表示尚未填充)。

您可以假设输入中的每个谜题都只有一个解决方案。

文件结尾处为包含单词“end”的单行,表示输入结束。

输出格式

每个测试用例,输出一行数据,代表填充完全后的数独。

输入样例:

4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end

输出样例:

417369825632158947958724316825437169791586432346912758289643571573291684164875293
416837529982465371735129468571298643293746185864351297647913852359682714128574936

 题解:首先考虑每行,每列,每个九宫格的数只能出现一次的限制,我们利用九位的二进制数进行限制,初始为9位都是1,使用的之后的那位变为0,然后,每次先用row[x] & col[y] & cell[x/3][y/3]找到那个点的限制的九位数,利用lowbit运算取出可以用的数,然后我们考虑优化搜索顺序,每次找到可选数字最少的点进行填充(这样可以使搜索分支变少)。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast","inline")
#include
using namespace std;
#define ll long long 
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,b,a) for(int i=b;i>=a;i--)
#define Mst(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&-x
#define x first
#define y second
const int N = 9;
typedef pair PII;
string str;
int row[9],col[9],cell[3][3],ones[1<<10];
unordered_map mp;
void init() {
    rep(i,0,8) {
        row[i] = (1< ones[state]) {
				minn = ones[state];
				x = i; y = j;
			}
		}
	}
	
	int state = get(x,y);
	
	for(int i = state;i;i -= lowbit(i)) {
		  int d = lowbit(i);
		  int t = mp[lowbit(i)];
		  row[x] -= d;
		  col[y] -= d;
		  cell[x/3][y/3] -= d;
		  str[x * N + y] = char('1' + t);
		  dfs(cnt-1);
		  str[x * N + y] = '.';
		  row[x] += d;
		  col[y] += d;
		  cell[x/3][y/3] += d;	
	}
}
int main() {
    
       ios::sync_with_stdio(false);
         cin.tie(0);
       
	    rep(i,0,8) mp[1<> j) & 1;
		  } 
		} 
    while(cin >> str && str != "end") {
         init();
         int len = str.size();
         
         int cnt = 0;
         rep(i,0,len-1) {
         	 if(str[i] == '.') {
         	 	  cnt++;continue;
			  }
             int x = i/9,y = i%9,c = str[i] - '1';
             row[x] -= (1<

 

你可能感兴趣的:(dfs)