[LuoguP1074]靶形数独_搜索
靶形数独
题目链接:https://www.luogu.org/problem/P1074
数据范围:略。
题解:
传说中的大爆搜题啊。
我觉得这种题就是你能想到什么优化就直接上什么优化....
这个题我们就贪心的选行,就是按照每行$0$的个数从小到大排序依次填。
然后我们填的时候需要记录:当前要填的数,在行、列、九宫格里是否出现过即可。
还有,分数是$5\sim 10$,不是$1$到$5$.....
代码:
#include <bits/stdc++.h> #define N 110 using namespace std; char *p1, *p2, buf[100000]; #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ ) int rd() { int x = 0, f = 1; char c = nc(); while (c < 48) { if (c == '-') f = -1; c = nc(); } while (c > 47) { x = (((x << 2) + x) << 1) + (c ^ 48), c = nc(); } return x * f; } struct Node { int x, y; }; inline bool cmp(const Node &a, const Node &b) { return a.y < b.y; } const int n = 9; inline int id(Node a) { return n * (a.x - 1) + a.y; } inline int id(int x, int y) { return n * (x - 1) + y; } inline Node rz(int x) { return (Node) {(x - 1) / n + 1, (x - 1) % n + 1}; } inline int bid(int al) { int x = rz(al).x, y = rz(al).y; x = (x - 1) / 3 + 1, y = (y - 1) / 3 + 1; return (x - 1) * 3 + y; } int Map[N], q[N], Score[N], ans = 0, fil[N]; bool vis[3][10][10]; Node b[11]; void dfs(int k) { if (k == 82) { // puts("??"); int sum = 0; for (int i = 1; i <= n; i ++ ) { for (int j = 1; j <= n; j ++ ) { sum += fil[id(i, j)] * Score[id(i, j)]; } } // for (int i = 1; i <= n; i ++ ) { // for (int j = 1; j <= n; j ++ ) { // printf("%d ", fil[id(i, j)]); // } // puts(""); // } // puts(""); ans = max(ans, sum); return; } int x = rz(q[k]).x, y = rz(q[k]).y; // printf("%d %d\n", x, y); if (!Map[id(x, y)]) { for (int i = 1; i <= 9; i ++ ) { // x, y, i if (!vis[0][x][i] && !vis[1][y][i] && !vis[2][bid(id(x, y))][i]) { vis[0][x][i] = vis[1][y][i] = vis[2][bid(id(x, y))][i] = true; fil[id(x, y)] = i; dfs(k + 1); vis[0][x][i] = vis[1][y][i] = vis[2][bid(id(x, y))][i] = false; fil[id(x, y)] = 0; } } } else { dfs(k + 1); } } int main() { for (int i = 1; i <= 9; i ++ ) { for (int j = 1; j <= 9; j ++ ) { Map[id(i, j)] = rd(); } } for (int i = 1; i <= 9; i ++ ) { b[i].x = i; for (int j = 1; j <= 9; j ++ ) { int v = Map[id(i, j)]; if (!v) b[i].y ++ ; else { vis[0][i][v] = vis[1][j][v] = vis[2][bid(id(i, j))][v] = true; fil[id(i, j)] = v; } } } sort(b + 1, b + n + 1, cmp); for (int i = 1; i <= n; i ++ ) { for (int j = 1; j <= n; j ++ ) { int x = b[i].x, y = j; q[id(i, j)] = id(x, y); } } // init_score for (int i = 1; i <= n; i ++ ) { for (int j = 1; j <= n; j ++ ) { Score[id(i, j)] = 5; } } for (int i = 1; i <= 5; i ++ ) { int x = i, y = n - i + 1; for (int l = x; l <= y; l ++ ) { for (int r = x; r <= y; r ++ ) { Score[id(l, r)] ++ ; } } } // for (int i = 1; i <= n; i ++ ) { // for (int j = 1; j <= n; j ++ ) { // printf("%d ", Score[id(i, j)]); // } // puts(""); // } dfs(1); if (!ans) { puts("-1"); } else { cout << ans << endl ; } return 0; }
| 欢迎来原网站坐坐! >原文链接<