数独游戏

问题描述:
在9阶方阵中,包含了81个小格(九列九行),其中又再分成九个小正方形(称为宫),每宫有九小格。 游戏刚开始时,盘面上有些小格已经填了数字(称为初盘),游戏者要在空白的小格中填入1到9的数字, 使得最后每行、每列、每宫都不出现重复的数字,而且每一个游戏都只有一个唯一的解答(终盘)

代码:

#include <iostream>

using namespace std;
char maps[9][9];
typedef struct node{//用来存储当前为0 的结点,记录他们的x,y坐标

int x;
int y;

}node;
node blank[81];
int sum=0;



int store(char num,int xx,int yy){//看这个点是否能存储这一个数字
for(int i =0;i<9;i++){
    if(maps[i][yy]==num){
            return 0;
        //break;
    }
    if(maps[xx][i]==num){
        return 0;
        //break;
    }
}



//判断每个宫里面是否有相同的数字

int kh = xx - xx % 3;
	int kl = yy - yy % 3;
	for (int i = kh; i < kh + 3; i++)
	{
		for (int j = kl; j < kl + 3; j++)
		{
			if (maps[i][j] == num)
				return 0;
		}

	}
return 1;
}

//从第一个值为零的点开始深度遍历
int dfs(int n){
    if(n==sum){//递归出口
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                cout<<maps[i][j];
            }
            cout<<endl;

        }

       return 0;
    }
    else{
            for(int k=1;k<=9;k++){
                    char number=k+'0';
                if(store(number,blank[n].x,blank[n].y)==1){
                    maps[blank[n].x][blank[n].y]=number;
                    dfs(n+1);
                    maps[blank[n].x][blank[n].y]='0';//撤销选择
                }
            }

    }

return 0;
}

int main()
{
    for(int i=0;i<9;i++){//输入初始数据
        for(int j=0;j<9;j++){
            cin>>maps[i][j];
        }
    }
cout<<endl;
/*
    for(int i=0;i<9;i++){//输入初始数据
        for(int j=0;j<9;j++){
            cout<<maps[i][j];
        }
    }
*/

    //int sum=0;
for(int i=0;i<9;i++){//记录有多少个值为零的点
    for(int j=0;j<9;j++){
        if(maps[i][j]=='0'){
           blank[sum].x=i;
           blank[sum].y=j;
           sum++;
        }
    }
}
//开始遍历
dfs(0);




    return 0;
}

小结:
0、如果想要输入一行数字到数组中的一行时,需要定义成char类型的数组,否则,就要每输入一个数字敲一个空格,再进行下一个数字的输入。
1、在递归调用时,dfs(n++)是调用不起来的,应该是dfs(n+1)。
2、‘a’+1代表’b’
3、深度优先遍历所有可能的时候,下一个节点深搜完毕之后,要将前一个结点的状态恢复。
都是一些很小的问题,写在这里是为了让自己长教训(总是因为一个很小的错误浪费大量的时间排错~)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值