搜索树的概念
将搜索过程中每一步的状态变成树的一个接点;
根节点为搜索树的初始状态;
搜索便是不断扩展这棵树,直至找到目标状态位置;
搜索算法的优化和改正便在于如何拓展搜索树的节点;
解题第一步:如何将状态转化为树中的结点,并构造搜索树;
dfs:对于一个合法的状态A,对于其所有的子状态(搜索树的儿子结点),选择一种进行搜索,递归这一过程,直至到达叶子节点或目前状态不合法,则回溯至父亲节点,对另一种子状态进行搜索。
伪代码:
void dfs(状态A){
if(A不合法)return ;
if(A为目标状态)输出;
if(A不为目标状态)dfs(A+?)//递归调用
}
就是关于dfs有个很关键的地方就是return的处理,要严谨,对于递归的理解有很好的帮助,要找对关键点,防止出现比较恶心的错误,会心态炸的;
这道题首先要理解数独的概念,剩下的就是通过dfs寻找符合条件的数。知道最终找到答案;这道题还有一点关键之处在于对输入输出的处理;是联系dfs的好题;
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
#define INF 0x3f3f3f3f
#define inf -2100000000
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 100 + 10;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
int ret=0,f=0;char ch=getchar();
while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
return f?-ret:ret;
}
typedef pair<int, int>P;
P node[90];
int f = 0,cnt;
char m[10][10];
bool jud(int x, int y, int k){
for(int i = 0; i < 9; i++){
if(m[i][y] == k+'0')return false;
if(m[x][i] == k+'0')return false;
}
int tmpx = (x/3)*3;
int tmpy = (y/3)*3;
for(int i = tmpx; i < tmpx + 3; i++){
for(int j = tmpy; j < tmpy + 3; j++){
if(m[i][j] == k + '0') return false;
}
}
return true;
}
void dfs(int n){
if(f)return ;
if(n == cnt){
f = 1;
for(int i=0;i<9;++i){
cout<<m[i][0];
for(int j=1;j<9;++j){
cout<<' '<<m[i][j];
}
cout<<endl;
}
return ;
}
for(int i = 1; i<= 9; i++){
if(jud(node[n].first, node[n].second,i)){
m[node[n].first][node[n].second] = i + '0';
dfs(n+1);
}
if(f) return ;
}
m[node[n].first][node[n].second] = 0 + '0';
}
int main(){
int i,j;
while(1){
cnt = 0;
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
if(!(cin>>m[i][j]))exit(0);
if(m[i][j] == '?'){
node[cnt].first = i,node[cnt++].second = j;
continue;
}
}
}
if(f) cout << endl;
f = 0;
dfs(0);
}
return 0;
}
方法二代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
#define INF 0x3f3f3f3f
#define inf -2100000000
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 100 + 10;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
int ret=0,f=0;char ch=getchar();
while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
return f?-ret:ret;
}
typedef pair<int, int>P;
P node[90];
int cnt;
char m[10][10];
bool jud(int x, int y, int k){
for(int i = 0; i < 9; i++){
if(m[i][y] == k+'0')return false;
if(m[x][i] == k+'0')return false;
}
int tmpx = (x/3)*3;
int tmpy = (y/3)*3;
for(int i = tmpx; i < tmpx + 3; i++){
for(int j = tmpy; j < tmpy + 3; j++){
if(m[i][j] == k + '0') return false;
}
}
return true;
}
bool dfs(int n){
if(n == cnt)return true;
for(int i = 1; i<= 9; i++){
if(jud(node[n].first, node[n].second,i)){
m[node[n].first][node[n].second] = i + '0';
if(dfs(n+1))return true;
m[node[n].first][node[n].second] = '?';
}
}
return false;
}
void output(){
for(int i=0;i<9;++i){
cout<<m[i][0];
for(int j=1;j<9;++j){
cout<<' '<<m[i][j];
}
cout<<endl;
}
return ;
}
int main(){
int i,j;
int f = 0;
while(1){
cnt = 0;
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
if(!(cin>>m[i][j]))exit(0);
if(m[i][j] == '?'){
node[cnt].first = i,node[cnt++].second = j;
continue;
}
}
}
dfs(0);
if(f++)cout << endl;
output();
}
return 0;
}