【NOIP2009】靶形數獨
阿新 • • 發佈:2021-10-07
去連結裡看題目吧
解題思路
暴力 dfs
加剪枝即可。
-
先搜尋 \(0\) 的個數小的行。
-
用 \(vis_{0,i,j}\) 表示數字 \(j\) 在第 \(i\) 行是否出現過,\(vis_{1,i,j}\) 表示數字 \(j\) 在第 \(i\) 列是否出現過,\(vis_{2,i,j}\) 表示數字 \(j\) 在第 \(i\) 個九宮格里是否出現過。
-
用矩陣預處理需要的東西。
沒了。。。
AC CODE
#include <bits/stdc++.h> using namespace std; int read() { int x = 0; char c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } return x; } void write(int x) { if(x < 0) { putchar('-'); write(-x); return; } if(x > 9) write(x / 10); putchar(x % 10 + '0'); } int h[10][10] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 2, 2, 2, 3, 3, 3}, {0, 1, 1, 1, 2, 2, 2, 3, 3, 3}, {0, 1, 1, 1, 2, 2, 2, 3, 3, 3}, {0, 4, 4, 4, 5, 5, 5, 6, 6, 6}, {0, 4, 4, 4, 5, 5, 5, 6, 6, 6}, {0, 4, 4, 4, 5, 5, 5, 6, 6, 6}, {0, 7, 7, 7, 8, 8, 8, 9, 9, 9}, {0, 7, 7, 7, 8, 8, 8, 9, 9, 9}, {0, 7, 7, 7, 8, 8, 8, 9, 9, 9}}; int score[10][10] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {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}}; int Ans; bool flag; int a[10][10], ans[10][10]; int num, g[107]; int vis[3][107][107]; struct abc { int id, cnt; } k[10]; bool cmp(abc a, abc b) { return a.cnt < b.cnt; } int getans() { int Ans = 0; for(register int i = 1; i <= 9; ++i) for(register int j = 1; j <= 9; ++j) Ans += ans[i][j] * score[i][j]; return Ans; } void dfs(int u) { if(u == 82) { flag = 1; Ans = max(Ans, getans()); return; } int x, y; if(g[u] % 9) x = g[u] / 9 + 1, y = g[u] % 9; else x = g[u] / 9, y = 9; // cout << x << " " << y << endl; if(!a[x][y]) { for(int j = 1; j <= 9; ++j) { int G = h[x][y]; // cout << G << endl; if(!vis[0][x][j] && !vis[1][y][j] && !vis[2][G][j]) { ans[x][y] = j; vis[0][x][j] = vis[1][y][j] = vis[2][G][j] = 1; dfs(u + 1); vis[0][x][j] = vis[1][y][j] = vis[2][G][j] = 0; } } } else dfs(u + 1); } signed main() { for(register int i = 1; i <= 9; ++i) { int cnt = 0; for(register int j = 1; j <= 9; ++j) { a[i][j] = read(); if(!a[i][j]) cnt++; else { int v = a[i][j], g = h[i][j]; ans[i][j] = v; vis[0][i][v] = vis[1][j][v] = vis[2][g][v] = 1; } } k[i].id = i; k[i].cnt = cnt; } sort(k + 1, k + 9 + 1, cmp); for(register int i = 1; i <= 9; ++i) for(register int j = 1; j <= 9; ++j) { int x = k[i].id, y = j; g[++num] = (x - 1) * 9 + y; } dfs(1); if(flag) write(Ans); else write(-1); putchar('\n'); return 0; }
本文來自部落格園,作者:蒟蒻orz,轉載請註明原文連結:https://www.cnblogs.com/orzz/p/15376320.html