DFS之剪枝与优化-----数独

9*9的数独,输入一些数,输出完整的数独中的数,保证输入的数只有一个解。

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 9, M = 1 << N;
int ones[M], map[M];
int row[N], col[N], cell[3][3];
char str[100];
void init(){
 for (int i = 0; i < N; i ++)
    row[i] = col[i] = (i << N) - 1;
 for (int i = 0; i < 3; i ++)
    for (int j = 0; j < 3; j ++)
    cell[i][j] = (1 << N) - 1;
} 
int lowbit(int x){
 return x & -x;
}
void draw(int x, int y, int t, bool is_set){
 if (is_set)   str[x * N + y] = '1' + t;
 else          str[x * N + y] = '.';
 int v = 1 << t;
 if (!is_set)    v = -v;
 row[x] -= v;
 col[y] -= v;
 cell[x/3][y/3] -= v;
}
int get(int x, int y){
 return  row[x] & col[y] & cell[x/3][y/3];
}
bool dfs(int cnt){
 if (!cnt)    return true;
 int minv = 10;
 int x, y;
  for (int i = 0; i < N; i ++)
     for (int j = 0; j < N; j ++)
       if (str[i * N + j] == '.'){
        int state = get(i, j);
        if (ones[state] < minv){
         minv = ones[state];
         x = i, y = j;
     }
    }
     int state = get(x, y);
 for (int i = state; i; i -= lowbit(i)){
  int t = map[lowbit(i)];
  draw(x, y, t, true);
  if (dfs(cnt - 1))    return true;
  draw(x, y, t, false);
 }
 return false;
}
int main(){
 for (int i = 0; i < N; i ++)      map[1 << i] = i;
 for (int i = 0; i < 1 << N; i ++)
    for (int j = 0; j < N; j ++)
    ones[i] += i >> j & 1;
  while(cin >> str, str[0] != 'e'){
  init();
 int cnt = 0;
  for (int i = 0, k = 0; i < N; i ++)
     for (int j = 0; j < N; j ++, k ++)
     if (str[k] != '.'){
      int t = str[k] - '1';
      draw(i, j, t, true);
  }
  else   cnt ++;
  dfs(cnt);
  puts(str);
   }
     return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值