编程之美——构造数独
问题:
构造一个9*9的方格矩阵,玩家要在每个方格中,分别填上1至9的任意一个数字,
让整个棋盘每一列、每一行以及每一个3*3的小矩阵中的数字都不重复。
首先我们通过一个深度优先搜索来生成一个可行解,然后随机删除一定数量的数字,
以生成一个数独。
#include <iostream>
#include <cstdlib>
using namespace std;
#define LEN 9
#define CLEAR(a) memset((a), 0, sizeof(a))
int level[] = {30, 37, 45}; //要删除的数字个数数组
int grid[LEN+1][LEN+1]; //网格中每个坐标的值
int value[LEN+1]; //标记值
void next(int &x,int &y)
{
x++;
if(x>9)
{
x=1;
y++;
}
}
int pickNextValidValue(int x,int y,int cur)
{
CLEAR(value);
int i,j;
for(i=1;i<y;i++)
value[grid[i][x]]=1;
for(j=1;j<x;j++)
value[grid[y][j]]=1;
int u=(x-1)/3*3+1;
int v=(y-1)/3*3+1;
for(i=v;i<v+3;i++)
{
for(j=u;j<u+3;j++)
{
value[grid[i][j]]=1;
}
}
for(i=cur+1;i<=LEN&&value[i];i++);
return i;
}
void pre(int &x,int &y)
{
x--;
if(x<1)
{
x=9;
y--;
}
}
int main()
{
int x,y,i,j;
x=y=1;
while(true)
{
times++;
if(y==LEN&&x==LEN)
{
for(i=1;i<=LEN;i++)
{
for(j=1;j<=LEN;j++)
cout<<grid[i][j]<<" ";
cout<<endl;
}
cout<<endl;
break;
}
if(y==0)
break;
grid[y][x]=pickNextValidValue(x,y,grid[y][x]);
if(grid[y][x]>LEN)
{
grid[y][x]=0;
pre(x,y);
}
else
next(x,y);
}
for(i=1;i<=level[2];i++)
{
int ind=rand()%(LEN*LEN);
grid[ind/LEN+1][ind%LEN]=0;
}
for(i=1;i<=LEN;i++)
{
for(j=1;j<=LEN;j++)
cout<<grid[i][j]<<" ";
cout<<endl;
}
}
#include <cstdlib>
using namespace std;
#define LEN 9
#define CLEAR(a) memset((a), 0, sizeof(a))
int level[] = {30, 37, 45}; //要删除的数字个数数组
int grid[LEN+1][LEN+1]; //网格中每个坐标的值
int value[LEN+1]; //标记值
void next(int &x,int &y)
{
x++;
if(x>9)
{
x=1;
y++;
}
}
int pickNextValidValue(int x,int y,int cur)
{
CLEAR(value);
int i,j;
for(i=1;i<y;i++)
value[grid[i][x]]=1;
for(j=1;j<x;j++)
value[grid[y][j]]=1;
int u=(x-1)/3*3+1;
int v=(y-1)/3*3+1;
for(i=v;i<v+3;i++)
{
for(j=u;j<u+3;j++)
{
value[grid[i][j]]=1;
}
}
for(i=cur+1;i<=LEN&&value[i];i++);
return i;
}
void pre(int &x,int &y)
{
x--;
if(x<1)
{
x=9;
y--;
}
}
int main()
{
int x,y,i,j;
x=y=1;
while(true)
{
times++;
if(y==LEN&&x==LEN)
{
for(i=1;i<=LEN;i++)
{
for(j=1;j<=LEN;j++)
cout<<grid[i][j]<<" ";
cout<<endl;
}
cout<<endl;
break;
}
if(y==0)
break;
grid[y][x]=pickNextValidValue(x,y,grid[y][x]);
if(grid[y][x]>LEN)
{
grid[y][x]=0;
pre(x,y);
}
else
next(x,y);
}
for(i=1;i<=level[2];i++)
{
int ind=rand()%(LEN*LEN);
grid[ind/LEN+1][ind%LEN]=0;
}
for(i=1;i<=LEN;i++)
{
for(j=1;j<=LEN;j++)
cout<<grid[i][j]<<" ";
cout<<endl;
}
}
参考:http://blog.youkuaiyun.com/linyunzju/article/details/7673959