这份代码超时了,不过是我辛苦写出来的,一次纪念!!
用到了分块的思想,然后注意选最小值,还有一个就是每次update的时候你只需要一次就好了,因为所在行和列都没有那个更新的数。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int basr[90][10], basl[90][10], basg[90][10][10];
struct gridd
{
int i, j, value, num;
int gnum;
bool get;
int getvalue(int cnt)
{
int a = basr[cnt][i]; int b = basl[cnt][j];
value = (a&b) ^ (a^b);
a = (value&basg[cnt][i / 3][j / 3]);
b = (value^basg[cnt][i / 3][j / 3]);
value = a^b;
return value;
}
int getnum()
{
num = 0;
for (int i = 0; i < 9; i++)
{
if (((1 << i)&value) == 0)
num++;
}
return num;
}
};
gridd grid[90][90];
struct minn
{
int i, j;
int num;
};
minn minr[90][10];
void updater(int cnt,int i)
{
int nn = 0;
for (int j = 0; j < 9; j++)
{
if (grid[i][j].get == 1)
{
nn++;
continue;
}
grid[i][j].getvalue(cnt);
grid[i][j].getnum();
if (grid[i][j].num < minr[cnt][i].num)
{
minr[cnt][i].num = grid[i][j].num;
minr[cnt][i].i = i; minr[cnt][i].j = j;
}
}
if (nn == 9)
minr[cnt][i].num = 1000000000;
}
void updatel(int cnt, int j)
{
for (int i = 0; i < 9; i++)
{
if (grid[i][j].get == 1)
continue;
grid[i][j].getvalue(cnt);
grid[i][j].getnum();
if (grid[i][j].num < minr[cnt][i].num)
{
minr[cnt][i].num = grid[i][j].num;
minr[cnt][i].i = i; minr[cnt][i].j = j;
}
}
return;
}
void updateg(int cnt, int i, int j)
{
int i1 = (i / 3) * 3; int i2 = (i / 3 + 1) * 3;
int j1 = (j / 3) * 3; int j2 = (j / 3 + 1) * 3;
for (int p = i1; p < i2; p++)
{
if (p == i)
continue;
for (int q = j1; q < j2; q++)
{
if (q == j)
continue;
if (grid[p][q].get == 1)
continue;
grid[p][q].getvalue(cnt);
grid[p][q].getnum();
if (grid[p][q].num < minr[cnt][p].num)
{
minr[cnt][p].num = grid[p][q].num;
minr[cnt][p].i = p; minr[cnt][p].j = q;
}
}
}
return;
}
minn getmin(int cnt)
{
minn a = minn();
a.num = 1000000000;
for (int i = 0; i < 9; i++)
{
if (a.num>minr[cnt][i].num)
a = minr[cnt][i];
}
return a;
}
bool dfs(int cnt)
{
minn k = getmin(cnt);
if (k.num == 0)
return false;
if (k.num == 1000000000)
return true;
int p = k.i; int q = k.j;
grid[p][q].getvalue(cnt);
grid[p][q].get = 1;
for (int i = 0; i < 9; i++)
{
minr[cnt + 1][i] = minr[cnt][i];
basr[cnt + 1][i] = basr[cnt][i];
basl[cnt + 1][i] = basl[cnt][i];
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
basg[cnt + 1][i][j] = basg[cnt][i][j];
}
int times = 0;
for (int i = 0; i < 9; i++)
{
if ((1 << i)&grid[p][q].value)
continue;
grid[p][q].gnum = i + 1;
basr[cnt + 1][p] ^= (1 << i); basl[cnt + 1][q] ^= (1 << i);
basg[cnt + 1][p / 3][q / 3] ^= (1 << i);
if (!times){
minr[cnt + 1][p].num = 1000000000;
updater(cnt + 1, p);
updatel(cnt + 1, q);
updateg(cnt + 1, p, q);
}
if (dfs(cnt + 1))return true;
basr[cnt + 1][p] ^= (1 << i); basl[cnt + 1][q] ^= (1 << i);
basg[cnt + 1][p / 3][q / 3] ^= (1 << i);
times++;
}
grid[p][q].get = 0;
return false;
}
char s[100];
int main()
{
while (scanf("%s", s))
{
if (s[0] == 'e')
break;
for (int i = 0; i < 9; i++)
basr[0][i] = 0, basl[0][i] = 0;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
basg[0][i][j] = 0;
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
int k = i * 9 + j;
grid[i][j].i = i; grid[i][j].j = j;
if (s[k] == '.')
{
grid[i][j].get = 0;
}
else
{
grid[i][j].get = 1; grid[i][j].gnum = s[k] - '0';
basr[0][i] |= (1<<(s[k] - '0' - 1));
basl[0][j] |= (1<<(s[k] - '0' - 1));
basg[0][i / 3][j / 3] |=(1<< (s[k] - '0' - 1));
}
}
}
for (int i = 0; i < 9; i++)
minr[0][i].num = 100000000;
for (int i = 0; i < 9; i++)
updater(0, i);
dfs(0);
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
{
printf("%d", grid[i][j].gnum);
}
printf("\n");
}
return 0;
}