原题传送门
#include <bits/stdc++.h>
using namespace std;
struct consult_row_0 {//定义结构体,把行和这一行上0的个数捆绑起来
int row, num_0;
};
struct consult_row_0 dic_row_0[10];//查询第几行有几个0
int origin[10][10];//输入的数独
bool row[10][10], column[10][10], box[10][10];//存行,列,宫1~9的使用情况
int point_reach[100][4];//存到达点的x,y,box,value
int temp_max = -1;//初始化答案
int point_counter;//到达点的计数器
int origin_value;//数独原有已填数的价值和
int consult_box(int x, int y)//查询在第几宫
{
return (x - 1) / 3 * 3 + (y - 1) / 3 + 1;
}
int consult_value(int i, int j)//查询一个位置的价值数
{
if (i == 1 || i == 9 || j == 1 || j == 9)
{
return 6;
}
if (i == 2 || i == 8 || j == 2 || j == 8)
{
return 7;
}
if (i == 3 || i == 7 || j == 3 || j == 7)
{
return 8;
}
if (i == 4 || i == 6 || j == 4 || j == 6)
{
return 9;
}
return 10;
}
void dfs(int point_num_reach, int total_value_now)//字面意
{
if (point_num_reach == point_counter)//已经搜完
{
if (total_value_now > temp_max)//更新答案
{
temp_max = total_value_now;
}
return;
}
for (int i = 1; i <= 9; i++)//分1~9填数
{
if (row[point_reach[point_num_reach][0]][i] == false && column[point_reach[point_num_reach][1]][i] == false && box[point_reach[point_num_reach][2]][i] == false)//如果i在行列宫中没有出现
{
row[point_reach[point_num_reach][0]][i] = column[point_reach[point_num_reach][1]][i] = box[point_reach[point_num_reach][2]][i] = true;//标记出现
dfs(point_num_reach + 1, total_value_now + point_reach[point_num_reach][3] * i);//向下递归
row[point_reach[point_num_reach][0]][i] = column[point_reach[point_num_reach][1]][i] = box[point_reach[point_num_reach][2]][i] = false;//去标记
}
}
}
bool cmp(consult_row_0 a, consult_row_0 b)//排序用
{
return a.num_0 < b.num_0;
}
int main()
{
for (int i = 1; i <= 9; i++)
{
dic_row_0[i].row = i;//初始化列数,防止排序后信息丢失
}
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9; j++)
{
cin >> origin[i][j];//输入
if (origin[i][j] > 0)
{
row[i][origin[i][j]] = column[j][origin[i][j]] = box[consult_box(i, j)][origin[i][j]] = true;//记录输入数字在行列宫中出现
origin_value += origin[i][j] * consult_value(i, j);//统计当前现有价值
}
else
{
dic_row_0[i].num_0++;//统计行中0个数
}
}
}
sort(dic_row_0 + 1, dic_row_0 + 10, cmp);//按行中0个数升序排序
for (int i = 1; i <= 9; i++)//依次访问点
{
for (int j = 1; j <= 9; j++)
{
if (origin[dic_row_0[i].row][j] == 0)//如果未访问
{
point_reach[point_counter][0] = dic_row_0[i].row;//存当前到达点行列宫以及价值
point_reach[point_counter][1] = j;
point_reach[point_counter][2] = consult_box(dic_row_0[i].row, j);
point_reach[point_counter][3] = consult_value(dic_row_0[i].row, j);
point_counter++;//计数器+1
}
}
}
dfs(0, origin_value);//递归
cout << temp_max << endl;//输出
return 0;//完工大吉
}
对于行中未知数个数升序排序,减少搜索次数,然后电风扇