该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
#include
#include
#define null NULL
#define enter putchar(10)
#define space putchar(32)
#define rg(i, a, b, s) for(auto i = a; (b > a)?(i < b):(i > b); i += s)
#define INF USHRT_MAX
#define END LONG_LONG_MIN
#define var_name(x) #x
#define print_container(c) printf("Elements in container %s: \n", var_name(c)); for(auto x: c) {cout << to_string(x) << endl;}
using namespace std;
typedef long long ll;
typedef unsigned short int usi;
typedef unsigned int ui;
inline string to_string(string _s){
return(_s);
}
template
string to_string(pair p){
string _r = "
_r += to_string(p.first);
_r += ", ";
_r += to_string(p.second);
_r += ">";
return(_r);
}
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
usi sum = 0;
usi Matrix[9][9] = {0};
size_t _Hash(const pair &p){
return(2 * pow(p.first, 2) + 3 * pow(p.second, 3));
}
/*初始化时的点坐标集合*/
unordered_set, decltype(&_Hash)> s(0, _Hash);
/*后续填入的点坐标集合*/
unordered_set, decltype(&_Hash)> has_filled(0, _Hash);
ll num_of_solutions = 0;
inline void insert_pair(usi a, usi b){
s.insert(make_pair(a, b));
}
void Initiation(){
Matrix[5][2] = Matrix[0][8] = 1;
insert_pair(5, 2);
insert_pair(0, 8);
Matrix[0][5] = Matrix[4][1] = Matrix[1][8] = 2;
insert_pair(0, 5);
insert_pair(4, 1);
insert_pair(1, 8);
Matrix[6][0] = 3;
insert_pair(6, 0);
Matrix[2][6] = Matrix[5][5] = 4;
insert_pair(2, 6);
insert_pair(5, 5);
Matrix[8][1] = Matrix[7][6] = 5;
insert_pair(8, 1);
insert_pair(7, 6);
Matrix[3][0] = Matrix[1][4] = Matrix[6][1] = 6;
insert_pair(3, 0);
insert_pair(1, 4);
insert_pair(6, 1);
Matrix[7][2] = Matrix[8][5] = Matrix[5][3] = 7;
insert_pair(7, 2);
insert_pair(8, 5);
insert_pair(5, 3);
Matrix[3][4] = Matrix[8][8] = 8;
insert_pair(3, 4);
insert_pair(8, 8);
Matrix[0][1] = Matrix[8][0] = 9;
insert_pair(0, 1);
insert_pair(8, 0);
}
inline void print_matrix(){
rg(i, 0, 9, 1){
rg(j, 0, 9, 1){
if(s.find(make_pair(i, j)) != s.end()){
SetConsoleTextAttribute(handle, FOREGROUND_RED);
}else{
SetConsoleTextAttribute(handle, FOREGROUND_GREEN);
}
printf("%hu", Matrix[i][j]);
if(j < 8){
space;
}
}
enter;
}
SetConsoleTextAttribute(handle, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
}
/*获取a行b列位置的度,返回的是这个位置“附近”的数字集合,度就是该集合的size,显然在这个位置填入的数字不能在此集合中*/
inline unordered_set get_cnt(usi a, usi b){
unordered_set _s;
rg(i, a / 3 * 3, (a + 3) / 3 * 3, 1){
rg(j, b / 3 * 3, (b + 3) / 3 * 3, 1){
if(Matrix[i][j] != 0){
_s.insert(Matrix[i][j]);
}
}
}
rg(i, 0, 9, 1){
if(Matrix[a][i] != 0){
_s.insert(Matrix[a][i]);
}
if(Matrix[i][b] != 0){
_s.insert(Matrix[i][b]);
}
}
return(_s);
}
void do_fill(){
if(sum == 81 - s.size()){
printf("第%lld组解:\n", ++num_of_solutions);
print_matrix();
system("pause");
return;
}
/*index表示接下来找到的度最大(或之一)的位置坐标*/
pair index;
unordered_set t;
usi max_cnt = 0;
rg(i, 0, 9, 1){
rg(j, 0, 9, 1){
if(has_filled.find(make_pair(i, j)) != has_filled.end() || s.find(make_pair(i, j)) != s.end()){
continue;
}
unordered_set _t = get_cnt(i, j);
if(_t.size() > max_cnt){
max_cnt = _t.size();
index.first = i;
index.second = j;
t = _t;
}
}
}
//printf("row: %hu, column: %hu\n", index.first, index.second);
//print_container(t);
rg(i, 0, 9, 1){
/*剪枝:在集合t中的数或者与此位置同行同列,或者在同一3*3区域内,不在此集合中的数可被选填*/
if(t.find(i + 1) == t.end()){
Matrix[index.first][index.second] = i + 1;
sum++;
has_filled.insert(index);
do_fill();
/*加上break就没有回溯搜索,只使用贪心策略求出一组解*/
//break;
Matrix[index.first][index.second] = 0;
sum--;
has_filled.erase(index);
}
}
}
int main(){
Initiation();
//print_container(s);
do_fill();
return 0;
}