13年9月25号写的数独程序,虽然不怎么高大上,不过还是记录下。。
#include<iostream>
#include<cstdio>
#include<stack>
#include<set>
using namespace std;
//每行、列、小九宫中未用数字
set<char>set_row[9];
set<char>set_col[9];
set<char>set_area[9];
char grid[10][10];
//保存正在尝试的填充
struct stak
{
char val;
int row;
int col;
stak(int r,int c,int v):val(v),row(r),col(c){}
stak(){}
};
stack<stak>stk;
//大于v的第一个未用数字,不大于v的为已经尝试但失败的数字,所以不再考虑
char get_val(int r,int c,int area,char v='*')
{
set<char>::iterator it1,it2,it3;
it1=set_row[r].begin();
it2=set_col[c].begin();
it3=set_area[area].begin();
while(1)
{
if(it1==set_row[r].end()||it2==set_col[c].end()||it3==set_area[area].end())
{
return '*';
}
if(*it1==*it2&&*it2==*it3)
{
if(*it1<=v)
{
it1++;
it2++;
it3++;
continue;
}
else break;
}
if(*it1<=*it2&&*it1<=*it3){it1++;continue;};
if(*it2<=*it1&&*it2<=*it3){it2++;continue;};
if(*it3<=*it1&&*it3<=*it2){it3++;continue;};
}
return *it1;
}
int main()
{
//while(1)
{
//清空栈
while(!stk.empty())
{
stk.pop();
}
for(int i=0;i<9;i++)
{
//初始化每行、列、小九宫的未用数字为1-9
set_row[i].clear();
set_col[i].clear();
set_area[i].clear();
for(int j=1;j<=9;j++)
{
set_row[i].insert(j+'0');
set_col[i].insert(j+'0');
set_area[i].insert(j+'0');
}
}
//读入数独
for(int i=0;i<9;i++)
{
scanf("%s",grid[i]);
}
//把每行、列、 小九宫中已有的数字从未用集合中去除
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(grid[i][j]=='*')continue;
int area_grid=i/3*3+j/3;
set_area[area_grid].erase(grid[i][j]);
set_row[i].erase(grid[i][j]);
set_col[j].erase(grid[i][j]);
}
}
//*表示该处为未填数字的格
char next='*';
while(1)
{
//找到最近的未填数字处
int r=-1,c=-1;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(grid[i][j]=='*')
{
r=i;c=j;break;
}
}
if(r!=-1&&c!=-1)break;
}
if(r==-1&&c==-1)break;
//在第几个小九宫中
int ar=r/3*3+c/3;
//next表示该位置已尝试过的最小值
char tmp=get_val(r,c,ar,next);
if(tmp!='*')
{
set_row[r].erase(tmp);
set_col[c].erase(tmp);
set_area[ar].erase(tmp);
stk.push(stak(r,c,tmp));
//printf("tmp %d %d %c \n",r,c,tmp);
grid[r][c]=tmp;
next='*';
}
else
{
if(stk.empty())
{
printf("input maybe error!or bug??\n");
}
stak s=stk.top();
stk.pop();
set_row[s.row].insert(s.val);
set_col[s.col].insert(s.val);
set_area[s.row/3*3+s.col/3].insert(s.val);
grid[s.row][s.col]='*';
next=s.val;
}
}
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
printf("%c ",grid[i][j]);
}
printf("\n");
}
}
return 0;
}