C语言数独游戏求解

news/2024/11/23 1:49:57/

数独游戏的解法:

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


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


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


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


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

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

下面是代码

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

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

题目链接:

链接:http://pan.baidu.com/s/1hsiUOqo 密码:o9l5

#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++;}elseend=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;elsereturn 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;elsereturn 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';
}



http://www.ppmy.cn/news/563452.html

相关文章

POJ2676数独游戏题解

第三次才AC我好菜 一道“简单”的问题。 Description Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other c…

python解数独--世界最难数独2.3秒完成

“芬兰数学家因卡拉&#xff0c;花费3个月时间设计出了世界上迄今难度最大的数独游戏&#xff0c;而且它只有一个答案。因卡拉说只有思考能力最快、头脑最聪明的人才能破解这个游戏。”这是英国《每日邮报》2012年6月30日的一篇报道。看完这个新闻就对数独有点感兴趣了&#xf…

puzzle(0111)《数独》

目录 一&#xff0c;标准数独&#xff08;规则数独&#xff09; 1&#xff0c;规则 2&#xff0c;隐含规则 3&#xff0c;对称性 4&#xff0c;斜线数独 二&#xff0c;标准数独校验、求解 力扣 36. 有效的数独 POJ 3074 Sudoku POJ 2676 Sudoku HDU 1426 Sudoku Kil…

数独解题器强化版

经过实际测试&#xff0c;在解决高难度数独时&#xff0c;解题器的效果仍旧不理想&#xff0c;所以添加了数字提示功能。 另外添加了自定义数独数据功能。 MainWindow.xaml <Window x:Class"SudokuSolver.MainWindow"xmlns"http://schemas.microsoft.com/…

【开源】完美破解九宫格(数独)游戏

数独是一种比较费时费脑的游戏&#xff0c;一般难度的数独玩下来也得1个小时左右&#xff0c;本人是伪数独爱好者&#xff0c;碰到难点的数独需要花上若干个小时&#xff0c;于是偷懒写了一套破解程序&#xff0c;特拿出来分享&#xff0c;希望有人喜欢。 思路&#xff1a; 1、…

经典数独游戏+数独求解器—纯C语言实现

“心常乐数独小游戏”&#xff08;以下简称“本软件”&#xff09;是一款windows平台下的数独游戏软件。 本软件是开源、免费软件。 本软件使用纯C语言编写&#xff0c;MinGW编译&#xff0c;NSIS打包。 本软件主要特性如下&#xff1a; 支持“闯关模式”和“选关模式” 支…

python实现简易数独小游戏

起源 既然“数独”有一个字是“数”&#xff0c;人们也往往会联想到数学&#xff0c;那就不妨从大家都知道的数学家欧拉说起&#xff0c;但凡想了解数独历史的玩家在网络、书籍中搜索时&#xff0c;共同会提到的就是欧拉的“拉丁方块&#xff08;Latin square&#xff09;”。…

1.数独游戏(生成题目解唯一)

前几天在玩数独游戏的时候&#xff0c;产生了一个大胆的想法&#xff1a; 数独app上的题目都是现成的&#xff0c;干脆自己写一个可以随机生成数独的程序算了 一、需求提出&#xff1a; 1.随机生成数独题目&#xff0c;要求该题目有解&#xff08;有一个解最好&#xff09;&a…