當前位置:首頁 » 編程語言 » c語言求數獨
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言求數獨

發布時間: 2022-12-07 14:01:17

⑴ 用c語言如何隨機生成一個數獨

數獨生成演算法?這個還真不好搞,不過我當初寫數獨游戲的時候隨便搗鼓出來過一個,你自己去改改吧,至於這個演算法能不能生成所有的數獨,我還真沒論證過。

原理:對一個給出的數獨棋盤的所有行或列交換給出的兩個數X、Y,數組仍滿足數獨規則。如給出1、2,則對所有列交換1、2的位置,數組仍滿足數獨規則。

由於對棋盤的演進是隨機的,所以相當於隨機生成數獨棋盤啦。每次演進的次數最好大一點,10次以上吧,以保證每個數都被換過位置。

具體代碼就不用我寫了吧,嘎嘎……

⑵ C語言編寫一個3*3數獨,保證每行每列的和都相等!!求求各位大神了

/*
因為你說是數獨可是你只表述了行列相等,如果是數獨應該對角線相加也相等,所以我寫了兩個判斷函數,judge1為對角線也相等的情況,judge為你描述的行列和相等(情況太多了)
結題方案只需要做一次dfs就可以了,還需要配合一個棧來存儲dfs的路徑,將每個符合條件的路徑做一次行列和是否相等的判斷然後輸出就是要的結果!
*/
#include<stdio.h>
#include<memory.h>
#include<stdbool.h>
//stack
inta[9]={0};//a[0]--a[0][0]a[1]--a[0][1]andsoonsimulatestack
intlen=0;
//dfs
intvisited[10]={0};
booljudge()//行列相等
{
inti,j;
inttmp[6]={0};
for(i=0;i<3;i++)
for(j=0;j<3;j++)
tmp[i]+=a[3*i+j];
for(i=0;i<3;i++)
for(j=0;j<3;j++)
tmp[3+i]+=a[i+3*j];
intjud=tmp[0];
for(i=1;i<6;i++)
{
if(jud!=tmp[i])
returnfalse;
}
returntrue;
}
booljudge1()//行列相等對角線也相等
{
inti,j;
inttmp[8]={0};
for(i=0;i<3;i++)
for(j=0;j<3;j++)
tmp[i]+=a[3*i+j];
for(i=0;i<3;i++)
for(j=0;j<3;j++)
tmp[3+i]+=a[i+3*j];
tmp[7]=a[0]+a[4]+a[8];
tmp[6]=a[2]+a[4]+a[6];
intjud=tmp[0];
for(i=1;i<8;i++)
{
if(jud!=tmp[i])
returnfalse;
}
returntrue;
}
voidprinta()
{
intt,p;
for(t=0;t<3;t++)
{
for(p=0;p<3;p++)
{
printf("%d",a[3*t+p]);
}
printf(" ");
}
}
voiddfs(inti,intv[])
{
if(i==10)//findonesolution
{
if(judge1())//給你寫了兩個判斷函數如果對角線也相等那麼用judge1()即可判斷
printa();
return;
}

intj;
for(j=1;j<=9;j++)
{
inttmp[10];
memcpy(tmp,v,10*sizeof(int));
if(tmp[j]==0)
{
tmp[j]=1;
a[len++]=j;
//printf("%d%d ",len-1,a[len-1]);
dfs(i+1,tmp);
len--;
}

}


}
intmain(void)
{
dfs(1,visited);
return0;
}

⑶ c語言編寫的解數獨程序

#include <windows.h>
#include <stdio.h>
#include <time.h>

char sd[81];
bool isok = false;

//顯示數獨
void show()
{
if (isok) puts("求解完成");
else puts("初始化完成");

for (int i = 0; i < 81; i++)
{
putchar(sd[i] + '0');
if ((i + 1) % 9 == 0) putchar('\n');
}
putchar('\n');
}

//讀取數獨
bool Init()
{
FILE *fp = fopen("in.txt", "rb");
if (fp == NULL) return false;
fread(sd, 81, 1, fp);
fclose(fp);
for (int i = 0; i < 81; i++)
{
if (sd[i] >= '1' && sd[i] <= '9') sd[i] -= '0';
else sd[i] = 0;
}
show();
return true;
}

//遞歸解決數獨
void force(int k)
{
if (isok) return;
if (!sd[k])
{
for (int m = 1; m <= 9; m++)
{
bool mm = true;
for (int n = 0; n < 9; n++)
{
if ((m == sd[k/27*27+(k%9/3)*3+n+n/3*6]) || (m == sd[9*n+k%9]) || (m == sd[k/9*9+n]))
{
mm = false;
break;
}
}
if (mm)
{
sd[k] = m;
if (k == 80)
{
isok = true;
show();
return;
}
force(k + 1);
}
}
sd[k] = 0;
}
else
{
if (k == 80)
{
isok = true;
show();
return;
}
force(k + 1);
}
}

int main()
{
system("CLS");
if (Init())
{
double start = clock();
force(0);
printf("耗時%.0fms", clock() - start);
}
else puts("初始化錯誤");
getchar();
}

⑷ 求用C語言編一個解九宮格數獨的程序

前兩天剛寫完,還沒優化,已運行通過了.
暈,一維的好麻煩,這個也是碰巧前兩天剛寫好的,你看著自己修改下
#include
<stdio.h>
typedef
struct
{
int
line;
int
row;
int
num;
}Node;
int
main()
{
/*
int
a[9][9]={
{4,0,3,6,0,0,0,0,0},
{0,0,0,0,0,1,0,2,4},
{0,1,0,0,4,0,5,0,0},
{0,0,0,9,0,4,0,6,0},
{3,0,2,0,0,0,4,0,9},
{0,7,4,1,0,3,0,0,0},
{0,0,1,0,9,0,0,4,0},
{2,4,0,3,0,0,0,0,0},
{0,0,0,4,0,8,2,0,7}};
*/
int
a[9][9]={
{0,0,0,8,0,0,0,6,0},
{8,7,0,0,0,0,0,0,0},
{2,9,0,0,4,1,0,0,5},
{0,0,5,7,0,0,0,0,9},
{0,2,0,0,0,0,0,1,0},
{9,0,0,0,0,4,3,0,0},
{7,0,0,6,1,0,0,9,8},
{0,0,0,0,0,0,0,5,2},
{0,6,0,0,0,9,0,0,0}};
/*
int
a[9][9]={
{0,2,0,0,6,0,0,0,0},
{0,9,0,4,0,5,1,3,0},
{0,0,8,7,0,0,0,0,5},
{6,0,0,3,0,0,4,0,0},
{0,0,0,9,0,6,0,0,0},
{0,0,7,0,0,1,0,0,3},
{4,0,0,0,0,7,3,0,0},
{0,8,5,2,0,4,0,7,0},
{0,0,0,0,9,0,0,1,0}};
*/
/*
int
a[9][9]={
{0,0,3,0,2,0,0,0,6},
{0,0,2,0,9,0,0,0,4},
{7,0,0,8,0,0,2,0,3},
{0,8,0,0,7,0,5,0,0},
{0,7,0,1,0,6,0,3,0},
{0,0,0,2,0,0,0,9,0},
{4,0,6,0,0,8,0,0,5},
{6,0,0,0,4,0,3,0,0},
{9,0,0,0,1,0,7,0,0}};
*/
int
i,j,n,en,flag,y,k=0,x,qu,p,q;
Node
b[70];
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(!a[i][j])
{
b[k].line=i;
b[k].row=j;
b[k].num=0;
k+=1;
}
}
}
en=k;
/*從b[0]開始試,若b[k].num>9,則k-1,否則k+1*/
for(k=0;k<en;)
{
++b[k].num;
i=b[k].line;
j=b[k].row;
a[i][j]=b[k].num;
n=0;
while(n<9&&b[k].num<=9)
{
if(n==i)
{
for(y=0;y<9;y++)
{
if(y==j)
continue;
if(a[n][y]==a[i][j])
flag=1;
}
}
else
if(n==j)
{
for(y=0;y<9;y++)
{
if(y==i)
continue;
if(a[y][n]==a[i][j])
flag=1;
}
}
/*判斷同一塊中有沒有相同值*/
qu=3*(i/3)+j/3;
switch(qu)
{
case
0:x=0;
y=0;
break;
case
1:x=0;
y=3;
break;
case
2:x=0;
y=6;
break;
case
3:x=3;
y=0;
break;
case
4:x=3;
y=3;
break;
case
5:x=3;
y=6;
break;
case
6:x=6;
y=0;
break;
case
7:x=6;
y=3;
break;
default
:x=6;
y=6;
break;
}
p=x;
q=y;
for(;x<p+3;x++)
{
for(;y<q+3;y++)
{
if(x==i&&y==j)
continue;
if(a[x][y]==a[i][j])
{
flag=1;
break;
}
}
if(flag==1)
break;
}
if(flag==1)
{
a[i][j]=++b[k].num;
flag=0;
n=0;
continue;
}
n++;
}
if(b[k].num>9)
{
a[i][j]=b[k].num=0;
k--;
if(k<0)
{
printf("error!\r\n");
return
-1;
}
}
else
k++;
}
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
printf("%d",a[i][j]);
}
printf("\r\n");
}
return
1;
}

⑸ c語言 編程 數獨

當年我們做大程的時候本來也想做數獨來著,後來時間不夠沒做成.不知道專業人士怎麼編的,只能提供一點當時的思路給你,
1.9*9個格子對應一個數組A,數組的第一個值從0到9表示其中填的數字,0就是不填,另一個值表示它在桌面上的位置就是坐標
2.需要10張圖片,空白和9個數字
3.通過對滑鼠點擊的反應改變格子數組A的值,且將相應圖片覆蓋在相應坐標上
4.事先輸入若干組數組A的值(每組81個數),作為題庫
5.進行游戲時隨機抽取題庫中的一組,再隨機抽取若干格子顯示出來,其他留白.
6.填完後用三個循環判斷下每行每列每塊是否有相同的數字,沒有則通過.
具體編按鈕、放圖、滑鼠點擊響應等各種問題查一下書,有很多書上有很多教的這種一小段一小段的程序源代碼,直接抄下就行了。
加油^^

⑹ 求解數獨題,用C語言實現

回溯法(探索與回溯法)是一種選優搜索法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為「回溯點」。


#include<stdio.h>


intmap[9][9];


boolisPlace(intcount){

introw=count&#47;9;

intcol=count%9;

intj;

&#47;&#47;同一行

for(j=0;j<9;++j){

if(map[row][j]==map[row][col]&&j!=col){

returnfalse;

}

}

&#47;&#47;同一列

for(j=0;j<9;++j){

if(map[j][col]==map[row][col]&&j!=row){

returnfalse;

}

}

&#47;&#47;同一小格

inttempRow=row&#47;3*3;

inttempCol=col&#47;3*3;

for(j=tempRow;j<tempRow+3;++j){

for(intk=tempCol;k<tempCol+3;++k){

if(map[j][k]==map[row][col]&&j!=row&&k!=col){

returnfalse;

}

}

}

returntrue;

}


voidbacktrace(intcount){

if(count==81){

for(inti=0;i<9;++i){

for(intj=0;j<9;++j){

printf("%d",map[i][j]);

}

printf("&#92;n");

}

return;

}

introw=count&#47;9;

intcol=count%9;

if(map[row][col]==0){

for(inti=1;i<=9;++i){

map[row][col]=i;&#47;&#47;賦值

if(isPlace(count)){&#47;&#47;可以放

backtrace(count+1);&#47;&#47;進入下一層

}

}

map[row][col]=0;&#47;&#47;回溯

}else{

backtrace(count+1);

}

}


intmain()

{

charc;

for(inti=0;i<9;i++)

{

for(intj=0;j<9;j++)

{

scanf("%c",&c);

if(c=='.')map[i][j]=0;

elsemap[i][j]=c-'0';

}

scanf("%c",&c);&#47;&#47;接收換行符

}

backtrace(0);

return0;

}

⑺ 數獨 演算法 C語言 代碼

一、步驟:
1.對每一個空格,根據規則推斷它可能填入的數字,並存儲它的所有可能值;
2.根據可能值的個數,確定填寫的順序。比如說,有些空格只有一種可能,那必然是正確的結果,首先填入。
3.將所有隻有一種可能的空格填寫完畢以後,回到步驟1,重新確定剩下空格的可能值;
4.當沒有隻有一種可能的空格時(即每個空格都有兩種以上可能),按照可能值個數從小到大的順序,使用深度(廣度)優先搜索,完成剩下空格。

二、常式:

#include<windows.h>
#include<stdio.h>
#include<time.h>

charsd[81];
boolisok=false;

//顯示數獨
voidshow()
{
if(isok)puts("求解完成");
elseputs("初始化完成");

for(inti=0;i<81;i++)
{
putchar(sd[i]+'0');
if((i+1)%9==0)putchar(' ');
}
putchar(' ');
}

//讀取數獨
boolInit()
{
FILE*fp=fopen("in.txt","rb");
if(fp==NULL)returnfalse;
fread(sd,81,1,fp);
fclose(fp);
for(inti=0;i<81;i++)
{
if(sd[i]>='1'&&sd[i]<='9')sd[i]-='0';
elsesd[i]=0;
}
show();
returntrue;
}

//遞歸解決數獨
voidforce(intk)
{
if(isok)return;
if(!sd[k])
{
for(intm=1;m<=9;m++)
{
boolmm=true;
for(intn=0;n<9;n++)
{
if((m==sd[k/27*27+(k%9/3)*3+n+n/3*6])||(m==sd[9*n+k%9])||(m==sd[k/9*9+n]))
{
mm=false;
break;
}
}
if(mm)
{
sd[k]=m;
if(k==80)
{
isok=true;
show();
return;
}
force(k+1);
}
}
sd[k]=0;
}
else
{
if(k==80)
{
isok=true;
show();
return;
}
force(k+1);
}
}

intmain()
{
system("CLS");
if(Init())
{
doublestart=clock();
force(0);
printf("耗時%.0fms",clock()-start);
}
elseputs("初始化錯誤");
getchar();
}

⑻ 用c語言寫一個簡易數獨的思路。要代碼

#include<stdio.h>
intnum[9][9],xy[9][9];
intcheck(intx,inty){
inti,m,n;
for(i=0;i<9;i++)
if((xy[x][y]==xy[i][y]&&i!=x)||(xy[x][y]==xy[x][i]&&i!=y))
return0;
for(i=0,m=x/3*3,n=y/3*3;i<9;i++)
if(xy[x][y]==xy[m+i/3][n+i%3]&&m+i/3!=x&&n+i%3!=y)
return0;
return1;
}
voidsearch(intx,inty){
if(x==9)
for(x=0;x<9;x++){
for(y=0;y<9;y++)
printf("%d",xy[x][y]);
printf(" ");
}
elseif(num[x][y])
search(x+(y+1)/9,(y+1)%9);
else
for(xy[x][y]=1;xy[x][y]<=9;xy[x][y]++)
if(check(x,y))
search(x+(y+1)/9,(y+1)%9);
return;
}
intmain(){
inti,j;
for(i=0;i<9;i++)
for(j=0;j<9;j++){
scanf("%d",&num[i][j]);
xy[i][j]=num[i][j];
}
search(0,0);
return0;
}

輸入為9行9列整數,已知的整數填寫對應的數字,尚待計算的未知數字填寫0。

該代碼的思路很簡單,就是從第一行第一列開始依次填入數字,檢查是否是在同一行、同一列、同一宮有沒有填入重復數字,如果沒有就繼續填入下一個數字,如果有就返回。

雖然效率稍低,但原理簡單、表述直白、易於理解,更有效率的代碼是使用十字鏈表完成,如有興趣可繼續深入

⑼ 用C語言怎麼解數獨

#include<stdio.h>
#include<stdlib.h>

#defineSIZE9
#defineget_low_bit(x)((~x&(x-1))+1)

struct{
intleft;
charnum;
chartry;
}board[SIZE][SIZE];

intbit2num(intbit)
{
switch(bit){
case1:case2:
returnbit;
case4:
return3;
case8:
return4;
case16:
return5;
case32:
return6;
case64:
return7;
case128:
return8;
case256:
return9;
}
}

voidprintf_res()
{
inti,j,k;

for(i=0;i<SIZE;i++)
{
if(i%3==0)
{
for(j=0;j<SIZE*2+4;j++)
putchar('-');
putchar(' ');
}

for(j=0;j<SIZE;j++)
{
if(j%3==0)
putchar('|');
if(board[i][j].num>0)
printf("33[0;31m%2d33[0m",board[i][j].num);
else
printf("%2d",board[i][j].try);
}
printf("| ");
}
for(i=0;i<SIZE*2+4;i++)
putchar('-');
putchar(' ');
}

voidsub(inti,intj,intbit)
{
intk,m;

for(k=0;k<SIZE;k++)
{
board[k][j].left&=~bit;
board[i][k].left&=~bit;
}

for(k=i/3*3;k<(i/3+1)*3;k++)
for(m=j/3*3;m<(j/3+1)*3;m++)
board[k][m].left&=~bit;
}

voidinit()
{
inti,j;

for(i=0;i<SIZE;i++)
for(j=0;j<SIZE;j++)
if(board[i][j].num>0)
sub(i,j,1<<(board[i][j].num-1));
elseif(board[i][j].try>0)
sub(i,j,1<<(board[i][j].try-1));
}

voidadd(inti,intj,intbit)
{
intk,m;

for(k=0;k<SIZE;k++)
{
board[k][j].left|=bit;
board[i][k].left|=bit;
}
for(k=i/3*3;k<(i/3+1)*3;k++)
for(m=j/3*3;m<(j/3+1)*3;m++)
board[k][m].left|=bit;
}

voidsolve(intpos)
{
inti=pos/SIZE;
intj=pos%SIZE;
intbit,left;

if(pos==SIZE*SIZE)
{
printf_res();
exit(0);
}
if(board[i][j].num>0)
solve(pos+1);
else
for(left=board[i][j].left;left;left&=(left-1))
{
bit=get_low_bit(left);
sub(i,j,bit);
board[i][j].try=bit2num(bit);

solve(pos+1);

add(i,j,bit);
board[i][j].try=0;
init();
}
}

intmain()
{
inti,j,c;

for(i=0;i<SIZE;i++)
for(j=0;j<SIZE;j++)
{
while((c=getchar())<'0'||c>'9')
;
board[i][j].num=c-'0';
board[i][j].try=0;
board[i][j].left=0x0001FF;
}
init();
solve(0);

return0;
}

⑽ 急!C語言遞歸解數獨

我從網上隨便找個一個幫你改了改。首先把你要解的數獨放入一個文件sudo_input里,和你編譯後的exe文件在同一目錄。內容為:

1 0 0 0

0 0 0 2

0 0 4 0

0 3 0 0

代碼如下(備註:基本上這個也可以做9路甚至更多的,只需改動LENGTH和SUBLEN值即可):

#include<stdlib.h>
#include<stdio.h>

#defineLENGTH4
#defineSUBLEN2

intanswer=0;

voidprintSudo(intarray[][LENGTH]){
printf(" ");
inti,j;
for(i=0;i<LENGTH;i++){
if((i+1)%SUBLEN==0)
printf(" ");
for(j=0;j<LENGTH;j++){
if((j+1)%SUBLEN==0)
printf(" ");
printf("%d",array[i][j]);
}
printf(" ");
}
exit(0);
}


voidinitSudoArray(intarray[][LENGTH]){
inti,j;
FILE*fp;

if((fp=fopen("sudo_input","r"))==NULL){
printf("Fileopenfailed! ");
exit(-1);
}

for(i=0;i<LENGTH;i++){
for(j=0;j<LENGTH;j++){
fscanf(fp,"%d",&array[i][j]);
}
}

fclose(fp);
}


intcheckSudo(intarray[][LENGTH],inti,intj,inttestVal){
introw,col;
printf("checkSudofor[%d][%d]testVal=%d ",i,j,testVal);

//fixedtocolj,checkfortherows
for(row=0;row<LENGTH;row++){
printf("checkforrows![%d][%d]=%d ",row,j,array[row][j]);
if(array[row][j]==testVal)
return0;
}


//fixedtorowi,checkforcols
for(col=0;col<LENGTH;col++){
printf("checkforcols![%d][%d]=%d ",i,col,array[i][col]);
if(array[i][col]==testVal)
return0;
}


//checkforthesub-square
introw_subSquare=(i/SUBLEN)*SUBLEN;
intcol_subSquare=(j/SUBLEN)*SUBLEN;


printf("[%d][%d] ",row,col);
for(row=row_subSquare;row<row_subSquare+SUBLEN;row++){
for(col=col_subSquare;col<col_subSquare+SUBLEN;col++){
printf("checkforsub-square![%d][%d]=%d ",row,col,array[row][col]);
if(array[row][col]==testVal)
return0;
}
}

return1;
}


//
voidsudo_solve(intarray[][LENGTH],intlength){
//iforrows,jforcols
inti,j;


inttestVal;
inttempArray[LENGTH][LENGTH];


//mpthearraytotempArray
for(i=0;i<LENGTH;i++){
for(j=0;j<LENGTH;j++)
tempArray[i][j]=array[i][j];
}


i=length/LENGTH;
j=length%LENGTH;


printf("array[%d][%d]=%d",i,j,array[i][j]);
if(array[i][j]!=0){
//thereisavalintheslotarray[i][j]
if(length==80)
printSudo(tempArray);
else
sudo_solve(tempArray,length+1);
}else{
//thereisnovalintheslotarray[i][j]
for(testVal=1;testVal<=LENGTH;testVal++){
if(checkSudo(tempArray,i,j,testVal)!=0){

tempArray[i][j]=testVal;

if(length==LENGTH*LENGTH-1)
printSudo(tempArray);
else
sudo_solve(tempArray,length+1);

tempArray[i][j]=0;
}
}
}
}


intmain(void){
intarray[LENGTH][LENGTH];
initSudoArray(array);

sudo_solve(array,0);

if(answer==0)
printf("Thereisnoanswerforthissudo!");

return0;
}