数独游戏的深度优先遍历解法

数独
数独简介:
数独 是一种逻辑性的数字填充游戏,玩家须以数字填进每一格,而每行、每列和每个宫(即3x3的大格)有齐1至9所有数字。游戏设计者会提供一部份的数字,使谜题只有一个答案。一个已解答的数独其实是一种多了宫的限制的拉丁方阵,因为同一个数字不可能在同一行、列或宫中出现多于一次。
深度优先遍历算法:
学过数据结构的同学都知道,深度遍历算法最开始是为解决树的遍历发展出来的,而后用于图的遍历。就像走迷宫似的,走到一个点之后发现不能满足当前条件,于是必须得退回到前一个状态继续探索迷宫。主要思想过程我就不用再说了,本科期间大家已经很熟了。
算法过程分析:
先假设已经生成了一个数独谜题,例如上题中的数独谜题,先填第一行第二列中的空格,首先遍历横排,再遍历竖排,最后遍历方格。如此循环,如果碰到数字相同的情况,则需要换另外一个数字,如果1到9的全部数字情况都不满足的情况下,则需要返回到前一个状态,如果前一个状态还不满足,则继续返回知道满足在继续遍历。
算法代码:

#include <iostream>
using namespace std;
char map[10][10];
struct
{
    int h;
    int l;

}cor[90];
int count;
bool fit(char number,int x,int y)//判断是否符合填入条件
{
    int i,j;
    for(i=0;i<9;i++)
        if(map[x][i]==number||map[i][y]==number)
        return false;
    int kh=x-x%3;
    int kl=y-y%3;
    for(i=kh;i<kh+3;i++)
        for(j=kl;j<kl+3;j++)
        if(map[i][j]==number)
        return false;
    return true;
}
void search(int x)
{
    int i,j;
    if(x>count)//遍历成功则打印
    {
        for(i=0;i<9;i++)
        {
            for(j=0;j<8;j++)
                cout<<map[i][j]<<" ";
                cout<<map[i][8]<<endl;
        }
        return ;
    }
    for(i=1;i<=9;i++)
    {
        char number=i+'0';
        if(fit(number,cor[x].h,cor[x].l))
        {
            map[cor[x].h][cor[x].l]=number;
            search(x+1);//遍历下一个?处的数字
            map[cor[x].h][cor[x].l]='?';//需要改变到前一个状态
        }
    }
}
int main()
{
    int i,j;
    while(true)
    {
         count=-1;
        for(i=0;i<9;i++)
        for(j=0;j<9;j++){
            cin>>map[i][j];//用?号代替没有填入数字的空格
            if(map[i][j]=='?')
            {
                ++count;//记录空格的数量
                cor[count].h=i;//记录空格的行
                cor[count].l=j;//记录空格的列
            }
        }
        search(0);//开始遍历
        cout<<endl;
    }
    return 0;
}

测试事例:
谜题就用上图出现过的数字
这里写图片描述

测试后:

这里写图片描述

测试成功!!!!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值