skudo数独问题


There is really only one rule:


Fill in the grid so that
every row,
every column, and
every 3 x 3 box
contains the digits 1 through 9.


这个游戏只有一个规则:

将格子填满使得
每一行,
每一列,和
每一个小的九宫格
恰好包含1-9这9个数字

正是由于规则简单而又变化多端,数独一时间风靡全球。
现在,我们希望你能编写一个程序解决数独问题。

输入格式:

输入数据一共9行,每行有9个字符。
输入数据描述了一个待解决的数独,其中,“?”表示数独中的空缺。
我们的输入数据总保证有唯一解。

输出格式:

输出一共9行,每行9个数字,表示你的答案。

样例输入:

5????7??6
?6????5?4
?834?????
???182?4?
??1???9??
?7?369???
?????543?
1?5????9?
7??2????1

样例输出:

514927386
967831524
283456179
659182743
321574968
478369215
892615437
135748692
746293851

时间限制:

1000

空间限制:

32768
有时间再写一个dancinglinks。  读入很难,大家仔细体会一下。还可以加一个优化就是按每个格子已排除的数的个数从小到大排序后再搜。codevs上用inti()读入,输出时加一个空格
#include<bits/stdc++.h>
using namespace std;
int n,m;
int sz[10][10];
int heng[10][10],shu[10][10],jiu[4][4][10];
void init()
{
int count=0;
while (count<81)
{
bool pg=0;
char c;
scanf("%c",&c);
if (c=='?') count++;
if(c>='1'&&c<='9')
{
count++;
sz[(count-1)/9+1][count-((count-1)/9+1)*9+9]=c-'0';
}
}
}
void inti()
{
cin>>n;
int xx,yy,zz;
for(int i=1;i<=n;i++)
{
cin>>xx>>yy>>zz;
sz[xx][yy]=zz;
}
}
void inin()
{
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
cin>>sz[i][j];
}
void prepare()
{
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
{
heng[i][sz[i][j]]+=1;
shu[j][sz[i][j]]+=1;
jiu[((i-1)/3)+1][((j-1)/3)+1][sz[i][j]]+=1;
}
}
//READY
void print()
{
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
cout<<sz[i][j];
cout<<"\n";
}
}
void dfs(int depth)
{
if(depth>81) 
{
print();
return;
}
int x=(depth-1)/9+1,y=depth-x*9+9;
int aa=(x-1)/3+1;
int bb=(y-1)/3+1;
if(sz[x][y]) 
{
dfs(depth+1);
return;
}
for(int i=1;i<=9;i++)
{
if(heng[x][i]||shu[y][i]||jiu[aa][bb][i])
continue;
heng[x][i]++;shu[y][i]++;jiu[aa][bb][i]++;sz[x][y]=i;
dfs(depth+1);
heng[x][i]--;shu[y][i]--;jiu[aa][bb][i]--;sz[x][y]=0;
}
}
void doit()
{
dfs(1);
}


int main()
{
init();
//inti();
// inin();
prepare();
doit();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值