忙着复习,没时间写了,今天来道蓝题吧
传送门P1074 [NOIP2009 提高组] 靶形数独 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这题几个优化:
检查是否重复分别开R[i][j]表示第i行j是否出现,C表示列,与上同理,再开个B[i][j]表示第i个宫格
中j是否出现,计算xy所属宫格数的公式在代码第25行
另一个优化,计算每行0出现的个数,即没填个数,少的先dfs
最后一个优化,由上一个优化而来,开一个searchSources结构体数组,表示0的坐标
其排列顺序按上一个优化来算
上代码
#include <cstdio>
#include <algorithm>
using namespace std;
int map[10][10], size, res;
int score[10][10]{
{},
{0, 6, 6, 6, 6, 6, 6, 6, 6, 6},
{0, 6, 7, 7, 7, 7, 7, 7, 7, 6},
{0, 6, 7, 8, 8, 8, 8, 8, 7, 6},
{0, 6, 7, 8, 9, 9, 9, 8, 7, 6},
{0, 6, 7, 8, 9, 10, 9, 8, 7, 6},
{0, 6, 7, 8, 9, 9, 9, 8, 7, 6},
{0, 6, 7, 8, 8, 8, 8, 8, 7, 6},
{0, 6, 7, 7, 7, 7, 7, 7, 7, 6},
{0, 6, 6, 6, 6, 6, 6, 6, 6, 6}};
bool R[10][10], C[10][10], B[10][10];
struct {
int x, y;
} searchSources[100];
struct T1 {
int x, n;
} first[20];
inline int getCells(int x, int y) { return ((y - 1) / 3 * 3 + (x - 1) / 3 + 1); }
bool cmp(T1 a, T1 b) { return a.n < b.n; }
void dfs(int k) {
if (k > size) {
int sum = 0;
for (int i = 1; i <= 9; i++)
for (int j = 1; j <= 9; j++)
sum += map[i][j] * score[i][j];
res = max(res, sum);
return;
}
int x = searchSources[k].x, y = searchSources[k].y;
for (int i = 1; i <= 9; i++)
if (!R[x][i] && !C[y][i] && !B[getCells(x, y)][i]) {
R[x][i] = C[y][i] = B[getCells(x, y)][i] = true;
map[x][y] = i;
dfs(k + 1);
R[x][i] = C[y][i] = B[getCells(x, y)][i] = false;
map[x][y] = 0;
}
}
int main() {
//freopen("D:\\Projects\\C++\\IO\\input.txt", "r", stdin);
//freopen("D:\\Projects\\C++\\IO\\output.txt", "w", stdout);
for (int i = 1; i <= 9; i++)
first[i].x = i;
for (int i = 1; i <= 9; i++)
for (int j = 1; j <= 9; j++) {
scanf("%d", &map[i][j]);
if (map[i][j])
R[i][map[i][j]] = true, C[j][map[i][j]] = true, B[getCells(i, j)][map[i][j]] = true;
else first[i].n++;
}
sort(first + 1, first + 10, cmp);
for (int i = 1; i <= 9; i++)
for (int j = 1; j <= 9; j++)
if (!map[first[i].x][j])
searchSources[++size] = {first[i].x, j};
dfs(1);
res?printf("%d", res):printf("-1");
return 0;
}
QAQ
----end----