#include <bits/stdc++.h>
#define MAX_ROW 100
#define MAX_COL 100
using
namespace
std;
struct
Node
{
public
:
struct
Node *left;
struct
Node *right;
struct
Node *up;
struct
Node *down;
struct
Node *column;
int
rowID;
int
colID;
int
nodeCount;
};
struct
Node *header =
new
Node();
struct
Node Matrix[MAX_ROW][MAX_COL];
bool
ProbMat[MAX_ROW][MAX_COL];
vector <
struct
Node*> solutions;
int
nRow = 0,nCol = 0;
int
getRight(
int
i){
return
(i+1) % nCol; }
int
getLeft(
int
i){
return
(i-1 < 0) ? nCol-1 : i-1 ; }
int
getUp(
int
i){
return
(i-1 < 0) ? nRow : i-1 ; }
int
getDown(
int
i){
return
(i+1) % (nRow+1); }
Node *createToridolMatrix()
{
for
(
int
i = 0; i <= nRow; i++)
{
for
(
int
j = 0; j < nCol; j++)
{
if
(ProbMat[i][j])
{
int
a, b;
if
(i) Matrix[0][j].nodeCount += 1;
Matrix[i][j].column = &Matrix[0][j];
Matrix[i][j].rowID = i;
Matrix[i][j].colID = j;
a = i; b = j;
do
{ b = getLeft(b); }
while
(!ProbMat[a][b] && b != j);
Matrix[i][j].left = &Matrix[i][b];
a = i; b = j;
do
{ b = getRight(b); }
while
(!ProbMat[a][b] && b != j);
Matrix[i][j].right = &Matrix[i][b];
a = i; b = j;
do
{ a = getUp(a); }
while
(!ProbMat[a][b] && a != i);
Matrix[i][j].up = &Matrix[a][j];
a = i; b = j;
do
{ a = getDown(a); }
while
(!ProbMat[a][b] && a != i);
Matrix[i][j].down = &Matrix[a][j];
}
}
}
header->right = &Matrix[0][0];
header->left = &Matrix[0][nCol-1];
Matrix[0][0].left = header;
Matrix[0][nCol-1].right = header;
return
header;
}
void
cover(
struct
Node *targetNode)
{
struct
Node *row, *rightNode;
struct
Node *colNode = targetNode->column;
colNode->left->right = colNode->right;
colNode->right->left = colNode->left;
for
(row = colNode->down; row != colNode; row = row->down)
{
for
(rightNode = row->right; rightNode != row;
rightNode = rightNode->right)
{
rightNode->up->down = rightNode->down;
rightNode->down->up = rightNode->up;
Matrix[0][rightNode->colID].nodeCount -= 1;
}
}
}
void
uncover(
struct
Node *targetNode)
{
struct
Node *rowNode, *leftNode;
struct
Node *colNode = targetNode->column;
for
(rowNode = colNode->up; rowNode != colNode; rowNode = rowNode->up)
{
for
(leftNode = rowNode->left; leftNode != rowNode;
leftNode = leftNode->left)
{
leftNode->up->down = leftNode;
leftNode->down->up = leftNode;
Matrix[0][leftNode->colID].nodeCount += 1;
}
}
colNode->left->right = colNode;
colNode->right->left = colNode;
}
Node *getMinColumn()
{
struct
Node *h = header;
struct
Node *min_col = h->right;
h = h->right->right;
do
{
if
(h->nodeCount < min_col->nodeCount)
{
min_col = h;
}
h = h->right;
}
while
(h != header);
return
min_col;
}
void
printSolutions()
{
cout<<"Printing Solutions: ";
vector<
struct
Node*>::iterator i;
for
(i = solutions.begin(); i!=solutions.end(); i++)
cout<<(*i)->rowID<<" ";
cout<<"\n";
}
void
search(
int
k)
{
struct
Node *rowNode;
struct
Node *rightNode;
struct
Node *leftNode;
struct
Node *column;
if
(header->right == header)
{
printSolutions();
return
;
}
column = getMinColumn();
cover(column);
for
(rowNode = column->down; rowNode != column;
rowNode = rowNode->down )
{
solutions.push_back(rowNode);
for
(rightNode = rowNode->right; rightNode != rowNode;
rightNode = rightNode->right)
cover(rightNode);
search(k+1);
solutions.pop_back();
column = rowNode->column;
for
(leftNode = rowNode->left; leftNode != rowNode;
leftNode = leftNode->left)
uncover(leftNode);
}
uncover(column);
}
int
main()
{
nRow = 7;
nCol = 7;
for
(
int
i=0; i<=nRow; i++)
{
for
(
int
j=0; j<nCol; j++)
{
if
(i == 0) ProbMat[i][j] =
true
;
else
ProbMat[i][j] =
false
;
}
}
ProbMat[1][0] =
true
; ProbMat[1][3] =
true
;
ProbMat[1][6] =
true
; ProbMat[2][0] =
true
;
ProbMat[2][3] =
true
; ProbMat[3][3] =
true
;
ProbMat[3][4] =
true
; ProbMat[3][6] =
true
;
ProbMat[4][2] =
true
; ProbMat[4][4] =
true
;
ProbMat[4][5] =
true
; ProbMat[5][1] =
true
;
ProbMat[5][2] =
true
; ProbMat[5][5] =
true
;
ProbMat[5][6] =
true
; ProbMat[6][1] =
true
;
ProbMat[6][6] =
true
; ProbMat[7][0] =
true
;
ProbMat[7][3] =
true
;
createToridolMatrix();
search(0);
return
0;
}