您的位置:首页 > 其它

【hiho】数独

2016-06-15 15:22 316 查看
#define _CRT_SECURE_NO_WARNINGS

#include<vector>
#include<iostream>
#include<cstring>

using namespace std;

struct Node
{
Node(int x1, int y1) :x(x1), y(y1){}
int x;
int y;
Node* up;
Node* down;
Node* left;
Node* right;
};

class exactCover
{
public:
vector<int> solveExactCover();
exactCover(vector<vector<bool>>&);
vector<int> getAns()
{
return ans;
}

private:
int M; // Number of rows
int N; // Number of columns
Node* mRoot;
vector<Node*> mColumnLoc;
vector<int> mColumnCount;
vector<vector<Node*>> mNodeLoc;
void cover(int);
void uncover(int);
vector<int> ans;
bool dfs();
};

vector<vector<bool>> Suduko2ExactCover(vector<vector<int>>& a, vector<vector<int>>& list)
{
vector<vector<bool>> ret;
int M = 0;
int N = 81 * 4;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
{
int st = 1;
int en = 9;
if (a[i][j]) st = en = a[i][j];
for (int k = st; k <= en; k++)
{
auto tmp = vector<bool>(N, false);
tmp[81 * 0 + i * 9 + k - 1] = true;
tmp[81 * 1 + j * 9 + k - 1] = true;
tmp[81 * 2 + i * 9 + j] = true;
tmp[81 * 3 + (i / 3 * 3 + j / 3) * 9 + k - 1] = true;
ret.push_back(tmp);
list.push_back(vector<int>{i, j, k});
}
}
return ret;
}

int main()
{

int T;
cin >> T;
while (T--)
{
auto a = vector<vector<int>>(9, vector<int>(9, 0));
vector<vector<int>> list;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
cin >> a[i][j];
auto para = Suduko2ExactCover(a, list);

exactCover inst(para);
inst.solveExactCover();
auto u = inst.getAns();
for (auto x : u)
a[list[x][0]][list[x][1]] = list[x][2];
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
cout << a[i][j] << (j == 8 ? "\n" : " ");
}
return 0;
}

bool exactCover::dfs()
{
if (mRoot->right == mRoot) return true;
auto visitedRow = vector<bool>(M, false);
auto p = mRoot->right;
int minC = 100000;
int miny = -1;
Node* minp = nullptr;
while (p != mRoot)
{
if (mColumnCount[p->y] < minC)
{
minp = p;
miny = p->y;
minC = mColumnCount[p->y];
}
p = p->right;
}
if (!minC || miny == -1) return false;

bool solved = false;
p = minp->down;

cover(miny);

while (p != minp)
{
int currentX = p->x;
ans.push_back(currentX);

auto q = p->right;
while (q != p)
{
cover(q->y);
q = q->right;
}
if (!solved)
if (dfs()) return true;
q = p->left;
while (q != p)
{
uncover(q->y);
q = q->left;
}
ans.pop_back();
p = p->down;
}
uncover(miny);

return false;
}

vector<int> exactCover::solveExactCover()
{
dfs();
return ans;
}

exactCover::exactCover(vector<vector<bool>>& a)
{
ans.clear();
M = a.size();
if (!M) return;
N = a[0].size();

mColumnLoc = vector<Node*>(N, nullptr);
mColumnCount = vector<int>(N, 0);
mNodeLoc = vector<vector<Node*>>(M, vector<Node*>(N, 0));
mRoot = new Node(-1, -1);
vector<Node*>& cl = mColumnLoc;
vector<vector<Node*>>& l = mNodeLoc;

for (int i = 0; i < N; i++) cl[i] = new Node(-1, i);
mRoot->right = cl[0];
mRoot->left = cl[N - 1];
for (int i = 0; i < N; i++)
{
cl[i]->left = (i == 0 ? mRoot : cl[i - 1]);
cl[i]->right = (i == N - 1 ? mRoot : cl[i + 1]);
}
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
if (a[i][j]) l[i][j] = new Node(i, j);

for (int j = 0; j < N; j++)
{
auto p = cl[j];
for (int i = 0; i < M; i++)
if (a[i][j])
{
mColumnCount[j]++;
p->down = l[i][j];
l[i][j]->up = p;
p = l[i][j];
}
p->down = cl[j];
cl[j]->up = p;
}

for (int i = 0; i < M; i++)
{
Node* p = nullptr;
Node* head = nullptr;
for (int j = 0; j < N; j++)
if (a[i][j])
{
if (p == nullptr) head = p = l[i][j];
else
{
p->right = l[i][j];
l[i][j]->left = p;
p = l[i][j];
}
}
p->right = head;
head->left = p;
}
}

void exactCover::cover(int X)
{
auto head = mColumnLoc[X];

head->left->right = head->right;
head->right->left = head->left;
auto p = head->down;
while (p != head)
{
auto h1 = p;
auto q = h1->right;
while (q != h1)
{
mColumnCount[q->y]--;
q->up->down = q->down;
q->down->up = q->up;
q = q->right;
}
p = p->down;
}
}

void exactCover::uncover(int X)
{
auto head = mColumnLoc[X];

head->left->right = head;
head->right->left = head;
auto p = head->up;
while (p != head)
{
auto h1 = p;
auto q = h1->left;
while (q != h1)
{
mColumnCount[q->y]++;
q->up->down = q;
q->down->up = q;
q = q->left;
}
p = p->up;
}
}


dancing links

网上搜搜就有

特别要注意就是要逆向恢复

不得不说knuth的智商有点高

但是poj上的3074 TLE,我也是不服,各种贴出来说T的数据我都是秒出,算了,不理了

昨天晚上到今天纠结一个小错误

类里面的成员数据不初始化的话 有可能不是0的

就这个小错耗了N小时,让我发了两条朋友圈
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: