牛客一道小栗子 Sudoku
DFS+状态压缩+lowbit运算
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull;
typedef pair<long long, long long> pll;
const int N = 9, M = 1 << 9, mod = 2147483647;
const int inf = 0x3f3f3f3f, eps = 1e-6;
#define IOS \
ios::sync_with_stdio(0); \
cin.tie(0); \
cout.tie(0)
int cnt;
int row[N], col[N], cell[N], num[M], has[M];
char str[81];
inline int lowbit(int x) { return x & -x; }
inline void init() //初始化全为1【0表示填了,1表示未填】
{
for (int i = 0; i < N; i++)
row[i] = col[i] = cell[i] = (1 << N) - 1;
}
inline int get(int x, int y) { return row[x] & col[y] & cell[x / 3 * 3 + y / 3]; }
inline bool dfs(int cnt)
{
if (cnt == 0)
return 1;
int miv = 10, x, y;
for (int i = 0, k = 0; i < N; i++)
for (int j = 0; j < N; j++, k++)
if (str[k] == '.') //
{
int t = num[get(i, j)]; //找出剩余可填的数的个数
if (t < miv)
miv = t, x = i, y = j;
}
for (int i = get(x, y); i; i -= lowbit(i)) //依次尝试剩余能填的数
{
int t = has[lowbit(i)];
row[x] -= 1 << t;
col[y] -= 1 << t;
cell[x / 3 * 3 + y / 3] -= 1 << t;
str[x * 9 + y] = t + '1'; //第i行j列对应正好是第i*9+j个格子
if (dfs(cnt - 1))
return 1;
//还原现场
row[x] += 1 << t;
col[y] += 1 << t;
cell[x / 3 * 3 + y / 3] += 1 << t;
str[x * 9 + y] = '.';
}
return 0;
}
int main()
{
IOS;
for (int i = 1; i < M; i++) //
for (int j = i; j; j -= lowbit(j)) //找出i总共有几位是1
num[i]++;
for (int i = 0; i < N; i++)
has[1 << i] = i; //找出第几位是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] != '.')
{ //以9个为一个单位
int x = str[k] - '1';
row[i] -= 1 << x;
col[j] -= 1 << x;
cell[i / 3 * 3 + j / 3] -= 1 << x; //表示第x个数已经填了
}
else
cnt++;
dfs(cnt); //在循环里面
cout << str << endl;
}
return 0;
}