C语言数独游戏的求解方法

数独游戏的解法:

先将数独分为九个格子,用一个数组将每个小九宫格的候选数存放下来,将候选数挨个放进数独里的空位,如果这一行和这一列都没有这个数字,继续放入下一个,如果不能放入的话就回到上一步继续尝试,直到成功求出数独的解为止;

比如这个数独第一个九宫格的候选数就有1,2,7,8,9,我们需要从1开始放入第一个格子挨个尝试直到8的时候发现剩下的两个格子都不能放入

这个时候我们就要撤回上一个插入的7,发现8仍然不能放入,就继续撤回2,发现8可以放入,就将8放入3号位置,然后将9插入

这个时候我们发现2不能放入剩下的两格,我们就继续撤回到1插入的时候,将2放入1号位置,然后挨个放入剩下的数

循环这一过程,直到数独求出解为止;

这个方法比较容易想到,操作也比较容易实现

下面是代码

代码大多数都写了备注便于理解

题目需要的1000道题放在下面了,将这1000个txt文件拷到EXE文件同一目录就可以了

题目链接:数独题目

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 81
typedef struct asd{
 int x;//待测试的值的x坐标
 int y;//待测试的值的y坐标
 int p;//待测试的值的位置(1道9代表在九宫格里的位置)
 int n;//待测试的值
}A;
A zhan[MAX];//存放每个放进题目数组测试的数据
void kongque(int queshi[9][9],int aa[9][9]);//函数将候选数数组里去除题目中有的数字
void shuchu(int aa[9][9],int q);//输出整个数组到文件中
int end(int aa[9][9]); //判断是否结束
int next(int queshi[9][9],int m,int n,int *x,int *y,int aa[9][9]);//查找下一个应该放进九宫格测试的数据
int chazhao(int aa[9][9],int m,int n,int num);//查找同一行同一列是否有相同的值
int nfrz(int queshi[9][9],int aa[9][9],int m,int n,int *p);//判断是否满足入栈条件(就是当前值是否可以插入九宫格)
int rz(int *t,int x,int y,int p,int num);//入栈操作
int cz(int *t,int *x,int *y,int *p,int *num);//出栈操作
void aaaa(char aa[10],int a);//计算题目文件的文件名
void bbbb(char aa[10],int a);//计算答案文件的文件名
int main(){
 int i;//记录该调用哪道题
 for(i=0;i<1000;i++){
 int aa[9][9],j,k;//aa数组存放的是题目数独
 int queshi[9][9];//存放的是每个九宫格的待选数
 int end=0;//判断循环结束条件
 int h=0,l=0,p=1;//h是候选数的行坐标,l是候选数的列坐标,p代表当前测试数属于小九宫格的位置
 int t=-1;//栈的长度
 int s=0,num;
 FILE *u;
 char qwe[10];
 for(j=0;j<9;j++)//将数组置为每行都是(1到9)
 for(k=0;k<9;k++)
 queshi[j][k]=k+1;
 aaaa(qwe,i);
 u=fopen(qwe,"r");
 for(j=0;j<9;j++){//读入题目
 for(k=0;k<9;k++){
 fscanf(u,"%d",&aa[j][k]);
 }
 }
 fclose(u);
 memset(zhan,0,sizeof(zhan));//将栈的数据全部置为0
 kongque(queshi,aa);
 while(end!=1){//开始求解
 s=next(queshi,h,l,&h,&l,aa);//查找下一个应该放进九宫格测试的数据
 if(s==0){//如果找到则进入下一层
 s=nfrz(queshi,aa,h,l,&p);//判断能否插入数独里
 if(s==0){//如果可以则将插入的数据存放到栈里(入栈)
  s=rz(&t,h,l,p,queshi[h][l]);
  if(s==0){ //如果入栈成功则写入数独
  aa[h/3*3+(p-1)/3][h%3*3+(p-1)%3]=queshi[h][l];
  l++;//待选数跳到下一个
  p=1;//重新从第一个小格子开始判断是否插入
  }
  else{
  end=1;//循环结束
  }
 }
 else{
  s=cz(&t,&h,&l,&p,&num);
  if(s==0){//如果出栈成功则擦除插入的数据
  aa[h/3*3+(p-1)/3][h%3*3+(p-1)%3]=0;
  p++;
  }
  else
  end=1;
 }
 }
 else if(s==-1){
 shuchu(aa,i);//输出求解完毕的数独
 end=1;
 }
 else{
 printf("发生未知错误");
 end=1;
 }
 }
 }
 return 0;
}
//函数将候选数数组里去除题目中有的数字
void kongque(int queshi[9][9],int aa[9][9]){
 int i,j,x,y;
 for(i=0;i<j;i++){
 for(j=0;j<9;j++){
 if(aa[i][j]){
 x=i/3*3+j/3;//数独数组和候选数数组的坐标转换
 y=aa[i][j]-1;
 queshi[x][y]=0;
 }
 }
 }
}
//输出整个数组到文件中
void shuchu(int aa[9][9],int q){
 int i,j;
 FILE *p;
 char qq[10];
 bbbb(qq,q);
 p=fopen(qq,"w");
 for(i=0;i<9;i++){
 for(j=0;j<9;j++){
 fprintf(p,"%d ",aa[i][j]);
 }
 fprintf(p,"\n");
 }
 fclose(p);
}
//判断是否结束
int end(int aa[9][9]){
 int i,j,num=0;
 for(i=0;i<9;i++){
 num=0;
 for(j=0;j<0;j++){
 num+=aa[i][j];//检查每一行是否为1到9
 }
 if(num!=45)
 return -1;
 }
 for(j=0;j<9;j++){//检查每一列是否为1到9
 num=0;
 for(i=0;i<9;i++){
 num+=aa[i][j];
 }
 if(num!=45)
 return -1;
 }
 return 0;
}
//查找下一个应该放进九宫格测试的数据
int next(int queshi[9][9],int m,int n,int *x,int *y,int aa[9][9]){
 int qqq=0;
 if(n>8){//如果当前小九宫格填写完毕则进入下一个九宫格
 n=0;
 m++;
 }
 if(m>8){
 qqq=end(aa);//判断是否结束
 if(qqq!=0)
 return -1;
 else
 return 1;
 }
 while(queshi[m][n]==0){
 if(n<8)
 n++;
 else{
 n=0;
 m++;
 if(m>8){
 qqq=end(aa);
 if(qqq!=0)
  return -1;
 else
  return 1;
 }
 }
 }
 *x=m;//重新获取测试的值的x坐标和y坐标
 *y=n;
 return 0;
}
//查找同一行同一列是否有相同的值
int chazhao(int aa[9][9],int m,int n,int num){
 int i;
 for(i=0;i<9;i++){//查找行
 if(aa[m][i]==num)
 return -1;
 }
 for(i=0;i<9;i++){//查找列
 if(aa[i][n]==num)
 return -1;
 }
 return 0;
}
//判断是否满足入栈条件(就是当前值是否可以插入九宫格)
int nfrz(int queshi[9][9],int aa[9][9],int m,int n,int *p){
 int s=*p;
 int i,t1,t2,num;
 num=queshi[m][n];
 for(i=s;i<10;i++){
 t1=(m/3)*3+(s-1)/3;
 t2=(m%3)*3+(s-1)%3;
 if(aa[t1][t2]!=0){
 s++;
 continue;
 }
 if(chazhao(aa,t1,t2,num)!=0){
 s++;
 continue;
 }
 else{
 *p=s;
 return 0;
 }
 }
 return -1;
}
//入栈操作
int rz(int *t,int x,int y,int p,int num){
 if(*t>=MAX){
 return -1;
 }
 else{
 (*t)++;
 zhan[*t].x=x;
 zhan[*t].y=y;
 zhan[*t].p=p;
 zhan[*t].n=num;
 return 0;
 }
}
//出栈操作
int cz(int *t,int *x,int *y,int *p,int *num){
 if(*t==-1){
 return -1;
 }
 else{
 *x=zhan[*t].x;
 *y=zhan[*t].y;
 *p=zhan[*t].p;
 *num=zhan[*t].n;
 (*t)--;
 return 0;
 }
}
//计算题目文件的文件名
void aaaa(char aa[10],int a){
 if(a>=0&&a<10){
 aa[0]='0';
 aa[1]='0';
 aa[2]='0';
 aa[3]=a+'0';
 }
 else if(a<100){
 aa[0]='0';
 aa[1]='0';
 aa[2]=a/10+'0';
 aa[3]=a%10+'0';
 }
 else if(a<1000){
 aa[0]='0';
 aa[1]=a/100+'0';
 aa[2]=a/10%10+'0';
 aa[3]=a%10+'0';
 }
 aa[4]='.';
 aa[5]='t';
 aa[6]='x';
 aa[7]='t';
 aa[8]='\0';
}
//计算答案文件的文件名
void bbbb(char aa[10],int a){
 if(a>=0&&a<10){
 aa[0]='a';
 aa[1]='0';
 aa[2]='0';
 aa[3]=a+'0';
 }
 else if(a<100){
 aa[0]='a';
 aa[1]='0';
 aa[2]=a/10+'0';
 aa[3]=a%10+'0';
 }
 else if(a<1000){
 aa[0]='a';
 aa[1]=a/100+'0';
 aa[2]=a/10%10+'0';
 aa[3]=a%10+'0';
 }
 aa[4]='.';
 aa[5]='t';
 aa[6]='x';
 aa[7]='t';
 aa[8]='\0';
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C语言实现数独游戏的求解

    玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个同色九宫内的数字均含1-9,不重复. 输入包含9x9的已知数字,空位用0补齐,中间用空格隔开.(输入数独题目确保正确) 输出为输入数独题目的解. 样例输入: 8 0 0 0 0 0 0 0 0 0 0 3 6 0 0 0 0 0 0 7 0 0 9 0 2 0 0 0 5 0 0 0 7 0 0 0 0 0 0 0 4 5 7 0 0 0 0 0 1 0 0 0 3 0 0 0 1 0 0 0 0 6 8

  • C语言解数独程序的源码

    用C语言写的解数独的程序.在linux下测试成功运行. 效果如图: 这是带解的数独,需要填写的部分用数字0代替. 这是程序运行后的效果图.看看,数独已经搞定啦. 程序源码如下: #include <stdio.h> #include <stdlib.h> #define SIZE 9 #define get_low_bit(x) ((~x&(x-1))+1) struct{ int left; char num; char try; }board[SIZE][SIZE];

  • c++递归解数独方法示例

    复制代码 代码如下: #include<iostream> using namespace std; void init();void function(int m); int canplace(int row,int col,int c); void outputresult(); int a[9][9], maxm = 0; int main() {   init(); function(0);  return 0; } void init(){ int i, j; for(i = 0;

  • C语言数独游戏的求解方法

    数独游戏的解法: 先将数独分为九个格子,用一个数组将每个小九宫格的候选数存放下来,将候选数挨个放进数独里的空位,如果这一行和这一列都没有这个数字,继续放入下一个,如果不能放入的话就回到上一步继续尝试,直到成功求出数独的解为止: 比如这个数独第一个九宫格的候选数就有1,2,7,8,9,我们需要从1开始放入第一个格子挨个尝试直到8的时候发现剩下的两个格子都不能放入 这个时候我们就要撤回上一个插入的7,发现8仍然不能放入,就继续撤回2,发现8可以放入,就将8放入3号位置,然后将9插入 这个时候我们发现

  • C语言扫雷游戏的实现方法

    本文实例为大家分享了C语言扫雷游戏的实现代码,供大家参考,具体内容如下 实现扫雷 1.创建俩12*12的字符数组,一个用作放雷,一个呈现给用户 2.利用随机数往防雷数组中产生雷 3.设计呈现给用户的数组 4.利用输入坐标判断--如果有雷,游戏结束并呈现放雷数组:如果无雷,计算周围一圈雷的数量并显示 代码如下 头文件 #define _CRT_SECURE_NO_WARNINGS #pragma once #include<stdio.h> #include<windows.h> #

  • 易语言制作游戏的步骤方法

    下面就是小编带给大家的语言游戏教程方法操作,希望能够给你们带来一定的帮助,谢谢大家的观看. 1.图片,将视频,建议用会声会影.会声会影能够轻易地制作出非常有特效的视频,而AE则过于专业.软件自带许多模板. 2.用会声会影×5是非常受欢迎的视频编辑软件,插上你的视频(可以剪切,套用现成的片头片尾模板,功能很强大绝对能满足你的要求目前主流的有两款软件,简单易用功能强大. 3.既可以保留原来视频的声音.动画编辑合并制作电影或电子相册的好帮手哎,也可配上你的画外音(录音)或音乐.音频.图片,更多的用来制

  • 易语言做游戏辅助的方法

    学会易语言做辅助,就要先学会用CE来寻找游戏的基址,当然新手要从小游戏开始,我电脑没有什么大游戏,我就以超级玛丽奥为列 1,打开游戏和CE 2,打开游戏进程. 3,首次未知数值扫描 4,吃个蘑菇变大,选择变动的数值进行扫描 5,让人物变小,在选变动的数值扫描 6,这样反复搜索,最后得出 变小值为0 变大值为 1 6,打开易语言进行写挂 用一个时钟来控制无敌 7.编译,OK试试外挂 8.测试OK,碰到怪物就变大, 我这只是个列子,希望对你有用

  • C语言实现数独游戏

    本文实例为大家分享了C语言实现数独游戏的具体代码,供大家参考,具体内容如下 目标 写一个数独游戏,有以下功能: 1:能随机产生题目并给出答案. 2:求解输入的题目并输出答案. 实现说明 参照百度百科等资料可以知道求解数独的主要算法是:1.通过行.列和宫格确定可填数字.2.所有可行数字逐一填入得到结果.本程序求解数独部分也采用这样的算法.而生成题目的算法是: 随机产生一个长度为9的一维数组,元素是随机产生的1到9的不同数字.比如为root = [1, 4, 3, 5, 6 ,7, 8 ,9, 2]

  • 简单实现java数独游戏

    本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 打算把javaFx需要的组件装好以后直接用javaFx的,但似乎eclipse的版本不对,安装了也不能用... 数独代码是在之前寒假受命写的,学了一个月java的成果,现在看来有些不足但毕竟是第一个程序,就直接放上来,数独终盘的实现直接用了暴力,时间复杂度有点高,懒得改了直接放代码 终盘实现: import java.util.Random; public class SudokuPuzzleGenerator { pri

  • java版数独游戏核心算法(一)

    之前学习javascript时用javascript写过一个数独游戏,最近看了一点java的内容,于是就心血来潮想搞一个java版的数独游戏. 现在将全部代码分享出来和大家学习交流,当然代码中有着各种各样的问题和不足之处,望各位朋友批评指点. 以下是生成数独地图的核心算法,算法不是很好,也是之前参考过网上的一些思想: package hlc.shudu.src; /* * 数独的帮助类,里面提供数据所需的所有算法 */ public class ShuduHelper { //数独地图数组 pr

  • 基于Android实现数独游戏

    本文实例为大家分享了Android实现数独游戏的具体代码,供大家参考,具体内容如下 1.在src中有4个Java类: 其中代码分别是: Game.java: package com.example.test1; import android.R.integer; public class Game { public final String str="360000000004230800000004200" +"070460003820000014500013020"

  • 简单实现Android数独游戏

    本文实例为大家分享了Android数独游戏的具体代码,供大家参考,具体内容如下 实现了点击了相关的单元格之后会显示出对话框提示可选数字. 原始的自定义对话框仍旧不能满足我们的要求,原始的自定义对话框只能够生成Bulider对象  然后通过LayoutInflater获取相应的View 对象 (其实就是Layout 布局文件) 其实也是可以的,只是我们不能再次进行一些其他的操作了,比如说我们即使设置了TableLayout但是我们不能够在上面完成任何操作,因为并不允许使用 自定义方法设置相关功能,

随机推荐