亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C語(yǔ)言數(shù)獨(dú)游戲的求解方法

 更新時(shí)間:2022年03月24日 15:04:04   作者:簫鼓聲絕  
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言數(shù)獨(dú)游戲的求解方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

數(shù)獨(dú)游戲的解法:

先將數(shù)獨(dú)分為九個(gè)格子,用一個(gè)數(shù)組將每個(gè)小九宮格的候選數(shù)存放下來(lái),將候選數(shù)挨個(gè)放進(jìn)數(shù)獨(dú)里的空位,如果這一行和這一列都沒(méi)有這個(gè)數(shù)字,繼續(xù)放入下一個(gè),如果不能放入的話就回到上一步繼續(xù)嘗試,直到成功求出數(shù)獨(dú)的解為止;

比如這個(gè)數(shù)獨(dú)第一個(gè)九宮格的候選數(shù)就有1,2,7,8,9,我們需要從1開(kāi)始放入第一個(gè)格子挨個(gè)嘗試直到8的時(shí)候發(fā)現(xiàn)剩下的兩個(gè)格子都不能放入

這個(gè)時(shí)候我們就要撤回上一個(gè)插入的7,發(fā)現(xiàn)8仍然不能放入,就繼續(xù)撤回2,發(fā)現(xiàn)8可以放入,就將8放入3號(hào)位置,然后將9插入

這個(gè)時(shí)候我們發(fā)現(xiàn)2不能放入剩下的兩格,我們就繼續(xù)撤回到1插入的時(shí)候,將2放入1號(hào)位置,然后挨個(gè)放入剩下的數(shù)

循環(huán)這一過(guò)程,直到數(shù)獨(dú)求出解為止;

這個(gè)方法比較容易想到,操作也比較容易實(shí)現(xiàn)

下面是代碼

代碼大多數(shù)都寫了備注便于理解

題目需要的1000道題放在下面了,將這1000個(gè)txt文件拷到EXE文件同一目錄就可以了

題目鏈接:數(shù)獨(dú)題目

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#define MAX 81
typedef struct asd{
 int x;//待測(cè)試的值的x坐標(biāo) 
 int y;//待測(cè)試的值的y坐標(biāo) 
 int p;//待測(cè)試的值的位置(1道9代表在九宮格里的位置) 
 int n;//待測(cè)試的值
}A;
A zhan[MAX];//存放每個(gè)放進(jìn)題目數(shù)組測(cè)試的數(shù)據(jù) 
void kongque(int queshi[9][9],int aa[9][9]);//函數(shù)將候選數(shù)數(shù)組里去除題目中有的數(shù)字 
void shuchu(int aa[9][9],int q);//輸出整個(gè)數(shù)組到文件中 
int end(int aa[9][9]); //判斷是否結(jié)束 
int next(int queshi[9][9],int m,int n,int *x,int *y,int aa[9][9]);//查找下一個(gè)應(yīng)該放進(jìn)九宮格測(cè)試的數(shù)據(jù) 
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);//判斷是否滿足入棧條件(就是當(dāng)前值是否可以插入九宮格) 
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);//計(jì)算題目文件的文件名 
void bbbb(char aa[10],int a);//計(jì)算答案文件的文件名
int main(){
 int i;//記錄該調(diào)用哪道題 
 for(i=0;i<1000;i++){
 int aa[9][9],j,k;//aa數(shù)組存放的是題目數(shù)獨(dú) 
 int queshi[9][9];//存放的是每個(gè)九宮格的待選數(shù) 
 int end=0;//判斷循環(huán)結(jié)束條件 
 int h=0,l=0,p=1;//h是候選數(shù)的行坐標(biāo),l是候選數(shù)的列坐標(biāo),p代表當(dāng)前測(cè)試數(shù)屬于小九宮格的位置 
 int t=-1;//棧的長(zhǎng)度 
 int s=0,num;
 FILE *u;
 char qwe[10];
 for(j=0;j<9;j++)//將數(shù)組置為每行都是(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));//將棧的數(shù)據(jù)全部置為0 
 kongque(queshi,aa);
 while(end!=1){//開(kāi)始求解 
 s=next(queshi,h,l,&h,&l,aa);//查找下一個(gè)應(yīng)該放進(jìn)九宮格測(cè)試的數(shù)據(jù)
 if(s==0){//如果找到則進(jìn)入下一層 
 s=nfrz(queshi,aa,h,l,&p);//判斷能否插入數(shù)獨(dú)里 
 if(s==0){//如果可以則將插入的數(shù)據(jù)存放到棧里(入棧) 
  s=rz(&t,h,l,p,queshi[h][l]);
  if(s==0){ //如果入棧成功則寫入數(shù)獨(dú)
  aa[h/3*3+(p-1)/3][h%3*3+(p-1)%3]=queshi[h][l];
  l++;//待選數(shù)跳到下一個(gè) 
  p=1;//重新從第一個(gè)小格子開(kāi)始判斷是否插入 
  }
  else{
  end=1;//循環(huán)結(jié)束 
  }
 }
 else{
  s=cz(&t,&h,&l,&p,&num);
  if(s==0){//如果出棧成功則擦除插入的數(shù)據(jù) 
  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);//輸出求解完畢的數(shù)獨(dú) 
 end=1; 
 }
 else{
 printf("發(fā)生未知錯(cuò)誤");
 end=1;
 }
 }
 }
 return 0;
}
//函數(shù)將候選數(shù)數(shù)組里去除題目中有的數(shù)字 
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;//數(shù)獨(dú)數(shù)組和候選數(shù)數(shù)組的坐標(biāo)轉(zhuǎn)換 
 y=aa[i][j]-1;
 queshi[x][y]=0;
 }
 }
 }
}
//輸出整個(gè)數(shù)組到文件中
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);
}
//判斷是否結(jié)束
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;
}
//查找下一個(gè)應(yīng)該放進(jìn)九宮格測(cè)試的數(shù)據(jù) 
int next(int queshi[9][9],int m,int n,int *x,int *y,int aa[9][9]){
 int qqq=0;
 if(n>8){//如果當(dāng)前小九宮格填寫完畢則進(jìn)入下一個(gè)九宮格 
 n=0;
 m++;
 }
 if(m>8){
 qqq=end(aa);//判斷是否結(jié)束 
 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;//重新獲取測(cè)試的值的x坐標(biāo)和y坐標(biāo) 
 *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;
}
//判斷是否滿足入棧條件(就是當(dāng)前值是否可以插入九宮格) 
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;
 }
}
//計(jì)算題目文件的文件名 
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';
}
//計(jì)算答案文件的文件名
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';
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解C語(yǔ)言的void*空指針

    詳解C語(yǔ)言的void*空指針

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言的void*空指針,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • C++ Dijkstra算法之求圖中任意兩頂點(diǎn)的最短路徑

    C++ Dijkstra算法之求圖中任意兩頂點(diǎn)的最短路徑

    這篇文章主要為大家詳細(xì)介紹了用C++經(jīng)典算法-Dijkstra算法求任意兩頂點(diǎn)之間的最短路徑,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 基于C++17實(shí)現(xiàn)的手寫線程池

    基于C++17實(shí)現(xiàn)的手寫線程池

    本文主要介紹了基于C++17實(shí)現(xiàn)的手寫線程池,自己實(shí)現(xiàn)了Any類,Semaphore類以及Result類的開(kāi)發(fā),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • 使用C++和Direct3D (d3d)獲取屏幕截圖并根據(jù)傳入分辨率進(jìn)行縮放圖片大小(最新推薦)

    使用C++和Direct3D (d3d)獲取屏幕截圖并根據(jù)傳入分辨率進(jìn)行縮放圖片大小(最新推薦)

    這篇文章主要介紹了使用C++和Direct3D (d3d)獲取屏幕截圖并根據(jù)傳入分辨率進(jìn)行縮放圖片大小,本文給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • 淺析C語(yǔ)言中堆和棧的區(qū)別

    淺析C語(yǔ)言中堆和棧的區(qū)別

    堆和棧都是一種數(shù)據(jù)項(xiàng)按序排列的數(shù)據(jù)結(jié)構(gòu)。在C語(yǔ)言中是非常重要的知識(shí)點(diǎn),接下來(lái)通過(guò)本文給大家介紹C語(yǔ)言中堆和棧的區(qū)別,感興趣的朋友一起看下吧
    2016-06-06
  • c++ std::invalid_argument應(yīng)用

    c++ std::invalid_argument應(yīng)用

    想研究std::invalid_argument的朋友可以參考下
    2013-01-01
  • VC枚舉串口端口應(yīng)用

    VC枚舉串口端口應(yīng)用

    這篇文章主要介紹了VC枚舉串口端口應(yīng)用,羅列了常見(jiàn)的一些串口端口的應(yīng)用實(shí)例,需要的朋友可以參考下
    2014-10-10
  • C++中圖片重命名實(shí)現(xiàn)代碼

    C++中圖片重命名實(shí)現(xiàn)代碼

    這篇文章主要介紹了C++中圖片重命名實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2017-05-05
  • 深入理解C++移位運(yùn)算符

    深入理解C++移位運(yùn)算符

    下面小編就為大家?guī)?lái)一篇深入理解C++移位運(yùn)算符。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-05-05
  • C語(yǔ)言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)堆排序圖文示例

    C語(yǔ)言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)堆排序圖文示例

    這篇文章主要為大家介紹了C語(yǔ)言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)堆排序的圖文示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05

最新評(píng)論