传送门 | 难度 |
---|---|
https://www.luogu.com.cn/problem/P1074 | 提高+/省选- |
#include
#include
#include
#include
using namespace std;
const int N = 9;
bool line[N][N + 1];
bool col[N][N + 1];
bool r[N][N + 1];
const int cellindex[N][N] =
{{0,0,0,1,1,1,2,2,2},
{0,0,0,1,1,1,2,2,2},
{0,0,0,1,1,1,2,2,2},
{3,3,3,4,4,4,5,5,5},
{3,3,3,4,4,4,5,5,5},
{3,3,3,4,4,4,5,5,5},
{6,6,6,7,7,7,8,8,8},
{6,6,6,7,7,7,8,8,8},
{6,6,6,7,7,7,8,8,8}};
int shudu[N][N];
const int w[N][N] =
{{6,6,6,6,6,6,6,6,6},
{6,7,7,7,7,7,7,7,6},
{6,7,8,8,8,8,8,7,6},
{6,7,8,9,9,9,8,7,6},
{6,7,8,9,10,9,8,7,6},
{6,7,8,9,9,9,8,7,6},
{6,7,8,8,8,8,8,7,6},
{6,7,7,7,7,7,7,7,6},
{6,6,6,6,6,6,6,6,6} };
int res = -1;
bool visit[N][N];
inline void record() {
int sum = 0;
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
sum += shudu[i][j] * w[i][j];
if (sum > res)
res = sum;
}
inline void dfs(int cur) {
if (cur == 81) {
record();
return;
}
int xx = 0, yy = 0 , minrule = 233, cnt;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (visit[i][j])
continue;
cnt = 0;
for (int k = 1; k <= 9; ++k)
if (!line[i][k] && !col[j][k] && !r[cellindex[i][j]][k])
cnt++;
if (cnt < minrule) {
minrule = cnt;
xx = i;
yy = j;
}
}
}
int op = cellindex[xx][yy];
for (int i = 1; i <= 9; ++i)
if (!line[xx][i] && !col[yy][i] && !r[op][i]) {
line[xx][i] = col[yy][i] = r[op][i] = visit[xx][yy] = true;
shudu[xx][yy] = i;
dfs(cur + 1);
line[xx][i] = col[yy][i] = r[op][i] = visit[xx][yy] = false;
}
}
int main() {
int usednum = 0;
int sum = 0;
for (int i = 0; i < N; ++i){
for (int j = 0; j < N; ++j){
scanf("%d", &shudu[i][j]);
if (shudu[i][j] != 0) {
usednum++;
//sum += w[i][j] * shudu[i][j];
line[i][shudu[i][j]] = true;
col[j][shudu[i][j]] = true;
r[cellindex[i][j]][shudu[i][j]] = true;
visit[i][j] = true;
}
}
}
dfs(usednum);
cout << res << endl;
return 0;
}
状压了一下,好像没啥用。。还出现了一个1.02s的TLE。。。开了O2倒是挺快的
#include
#include
#include
#include
using namespace std;
const int N = 9;
int line[N];
int col[N];
int r[N];
int shudu[N][N];
const int w[N][N] =
{ {6,6,6,6,6,6,6,6,6},
{6,7,7,7,7,7,7,7,6},
{6,7,8,8,8,8,8,7,6},
{6,7,8,9,9,9,8,7,6},
{6,7,8,9,10,9,8,7,6},
{6,7,8,9,9,9,8,7,6},
{6,7,8,8,8,8,8,7,6},
{6,7,7,7,7,7,7,7,6},
{6,6,6,6,6,6,6,6,6} };
int res = -1;
const int cellindex[N][N] =
{ {0,0,0,1,1,1,2,2,2},
{0,0,0,1,1,1,2,2,2},
{0,0,0,1,1,1,2,2,2},
{3,3,3,4,4,4,5,5,5},
{3,3,3,4,4,4,5,5,5},
{3,3,3,4,4,4,5,5,5},
{6,6,6,7,7,7,8,8,8},
{6,6,6,7,7,7,8,8,8},
{6,6,6,7,7,7,8,8,8} };
inline void record() {
int sum = 0;
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
sum += shudu[i][j] * w[i][j];
if (sum > res)
res = sum;
}
inline bool check(int x, int y, int num) {
int tem = 1 << (num - 1);
if (line[x] & tem || col[y] & tem || r[cellindex[x][y]] & tem)
return false;
return true;
}
void dfs(int cur) {
if (cur == 81) {
record();
return;
}
int xx = 0, yy = 0, minrule = 233, cnt;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (shudu[i][j])
continue;
cnt = 0;
int ktem;
for (int k = 1; k <= 9; ++k) {
ktem = 1 << (k - 1);
if (!(line[i]&ktem) && !(col[j]&ktem) && !(r[cellindex[i][j]] & ktem))
cnt++;
}
if (cnt < minrule) {
minrule = cnt;
xx = i;
yy = j;
}
}
}
int op = cellindex[xx][yy];
for (int i = 1; i <= 9; ++i)
if (check(xx,yy,i)) {
int tem = 1 << (i - 1);
line[xx] |= tem;
col[yy] |= tem;
r[op] |= tem;
shudu[xx][yy] = i;
dfs(cur + 1);
tem = ~(tem);
line[xx] &= tem;
col[yy] &= tem;
r[op] &= tem;
shudu[xx][yy] = 0;
}
}
int main() {
int usednum = 0;
int sum = 0;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
scanf("%d", &shudu[i][j]);
if (shudu[i][j]) {
usednum++;
int ctem = 1 << (shudu[i][j] - 1);
line[i] |= ctem;
col[j] |= ctem;
r[cellindex[i][j]] |= ctem;
}
}
}
dfs(usednum);
cout << res << endl;
return 0;
}