1. 程式人生 > >nyoj 數獨

nyoj 數獨

每一個 for 推理 The 重復 sizeof 內存 flag 限制

數獨

時間限制:1000 ms | 內存限制:65535 KB 難度:4
描述

數獨是一種運用紙、筆進行演算的邏輯遊戲。玩家需要根據9×9盤面上的已知數字,推理出所有剩余空格的數字,並滿足每一行、每一列、每一個3*3宮內的數字均含1-9,不重復。 每一道合格的數獨謎題都有且僅有唯一答案,推理方法也以此為基礎,任何無解或多解的題目都是不合格的。

有一天hrdv碰到了一道號稱是世界上最難的數獨的題目,作為一名合格的程序員,哪能隨隨便便向困難低頭,於是他決定編個程序來解決它。。

技術分享圖片

輸入
第一行有一個數n(0< n <100),表示有n組測試數據,每組測試數據是由一個9*9的九宮格構成,0表示對應的格子為空
輸出
輸出一個9*9的九宮格,為這個數獨的答案
樣例輸入
1
0 0 5 3 0 0 0 0 0
8 0 0 0 0 0 0 2 0
0 7 0 0 1 0 5 0 0
4 0 0 0 0 5 3 0 0
0 1 0 0 7 0 0 0 6
0 0 3 2 0 0 0 8 0
0 6 0 5 0 0 0 0 9
0 0 4 0 0 0 0 3 0
0 0 0 0 0 9 7 0 0
樣例輸出
1 4 5 3 2 7 6 9 8 
8 3 9 6 5 4 1 2 7 
6 7 2 9 1 8 5 4 3 
4 9 6 1 8 5 3 7 2 
2 1 8 4 7 3 9 5 6 
7 5 3 2 9 6 4 8 1 
3 6 7 5 4 2 8 1 9 
9 8 4 7 6 1 2 3 5 
5 2 1 8 3 9 7 6 4 

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

bool flag;
int a[10][10];
//檢查每行每列每個3*3的矩陣中有沒有重復的數值
bool check(int x,int y,int num)
{
//判斷當前行
for(int i=0;i<9;++i)
if(a[x][i]==num)
return false;
//判斷當前列
for(int j=0;j<9;++j)
if(a[j][y]==num)
return false;
//每個3*3的矩陣
int X=x/3;
int Y=y/3;
for(int i=X*3;i<X*3+3;++i)
for(int j=Y*3;j<Y*3+3;++j)
if(a[i][j]==num)
return false;

return true;

}
//從當前位置開始搜索
void dfs(int x,int y)
{
if(flag)
return ;
if(x==9&&y==0)
{
flag=true;
for(int i=0;i<9;++i)
{
for(int j=0;j<9;++j)
cout<<a[i][j]<<" ";

cout<<endl;
}
return ;
}
//搜索到每一行的最後一個,換下一行
if(y==9)
dfs(x+1,0);
//如果這個位置有數字,跳過,一下一個位置為起點搜索
if(a[x][y]!=0)
dfs(x,y+1);
else
{
for(int i=1;i<10;++i)//依次判斷1-9折幾個數
{
if(check(x,y,i))//如果當前行,當前列,當前的3*3的矩陣沒有這個數字,
{
a[x][y]=i;
dfs(x,y+1);
a[x][y]=0;//如果填入的數不合適,去掉
}
}
}

}
int main()
{
int n;
cin>>n;
while(n--)
{
flag=false;
memset(a,0,sizeof(a));
for(int i=0;i<9;++i)
for(int j=0;j<9;++j)
cin>>a[i][j];
//freopen("2.txt","r",stdin);
dfs(0,0);
}
return 0;
}

nyoj 數獨