當前位置:首頁 » 編程軟體 » 數獨編程

數獨編程

發布時間: 2022-09-28 07:59:57

⑴ 基於SAT的數獨游戲求解程序,求c語言代碼

用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];

int bit2num(int bit)

{

switch(bit){

case 16:

case 256:

return 9;

基礎解法

排除法(摒除法)

摒除法:用數字去找單元內唯一可填空格,稱為摒除法,數字可填唯一空格稱為排除法 (Hidden Single)。

根據不同的作用范圍,摒余解可分為下述三種:

數字可填唯一空格在「宮」單元稱為宮排除(Hidden Single in Box),也稱宮摒除法。

數字可填唯一空格在「行」單元稱為行排除法(Hidden Single in Row),也稱行摒除法。

⑵ 數獨進入瓶頸了,求解!

編程進行了計算。本題只有一個唯一的解。

附代碼:

type x9

integer(1) :: a

integer(1) :: s(9)

integer(1) :: np

end type

type(x9) :: kk(9,9)

data kk%a/ &

0,0,0,0,0,4,0,0,3, &

0,0,0,6,0,8,0,5,0, &

8,0,7,0,3,0,6,0,0, &

0,0,0,1,0,0,9,7,0, &

0,5,0,9,6,3,0,2,0, &

0,1,2,0,0,0,0,0,8, &

0,0,5,0,2,0,4,0,7, &

0,8,0,3,0,9,0,0,0, &

1,0,0,4,0,0,0,0,0 /

kk%np=-kk%a

do i=1,9

do j=1,9

kk(j,i)%s=0

if(kk(j,i)%np.eq.0) then

do k=1,9

do il=1,9

if(kk(il,i)%a.eq.k) exit

end do

if(il.le.9) cycle

do ih=1,9

if(kk(j,ih)%a.eq.k) exit

end do

if(ih.le.9) cycle

ni=((i+2)/3-1)*3+1

nj=((j+2)/3-1)*3+1

do ih=ni,ni+2

do il=nj,nj+2

if(kk(il,ih)%a.eq.k) exit

end do

if(il.le.nj+2) exit

end do

if(ih.le.ni+2) cycle

if(il.le.nj+2) cycle

kk(j,i)%s(k)=k

end do

else

kk(j,i)%s(1)=kk(j,i)%a

end if

end do

end do

n=1

kk%a=0

kk%np=0

m=0

do while(.true.)

if(n.gt.81) exit

i=(n+8)/9

j=n-9*(i-1)

kk(j,i)%np=kk(j,i)%np+1

k=kk(j,i)%np

if(k.gt.9) then

if(n.eq.1) exit

kk(j,i)%a=0

n=n-1

cycle

else

kk(j,i)%a=0

end if

if(kk(j,i)%s(k).eq.0) then

cycle

else

do ih=1,i

if(kk(j,ih)%a.eq.kk(j,i)%s(k)) exit

end do

if(ih.le.i) cycle

do il=1,j

if(kk(il,i)%a.eq.kk(j,i)%s(k)) exit

end do

if(il.le.j) cycle

ni=((i+2)/3-1)*3+1

nj=((j+2)/3-1)*3+1

do ih=ni,i

do il=nj,nj+2

if(kk(il,ih)%a.eq.kk(j,i)%s(k)) exit

end do

if(il.le.nj+2) exit

end do

if(il.le.nj+2) cycle

if(ih.le.i) cycle

kk(j,i)%a=kk(j,i)%s(k)

if(n.eq.81) then

m=m+1

write(*,'(/,2x,a,i3)') 'find = ',m

do jj=1,9

write(*,'(1x,9i2)') kk(1:9,jj)%a

end do

else

n=n+1

i=(n+8)/9

j=n-9*(i-1)

kk(j,i)%np=0

cycle

end if

end if

end do

end

⑶ 誰能告訴我數獨游戲的編程思維啊

一、解數獨
1、標記
2、利用各種方法減少標記數量,例如顯性數對刪減法、隱形唯一數法、隱形數對法、區域刪減法、區塊刪減法、三四鏈數刪減法等等
3、填充,利用唯一值法,如果那個標記中只有一個可填了,這就是結果了。
4、假設法,如果各種方法(至少你知道的)都用了還是沒有唯一數,那隻能假設了,按一定順序某個單元格標記中假設一個就是要填充的數,然後重復上面的步驟,如果得到無解(就是出現某個單元格的沒有可填的數),那就退回,換一個數繼續。(一般這個過程用遞歸完成)
二、如何生成題目
會解數獨後,生成就不是問題了,我的方法是分為兩步首先隨機填充1-9到第一行,然後用上訴方法產生一個解。再次,隨機一個一個數刪除,每刪除一個數重復上訴方法,看看是否是唯一解,如果是繼續刪除(不是就恢復,刪其它的),直到達到一定目的為止。這樣就產生一個數獨題目。

⑷ 怎麼用excel做數獨游戲

用excel做數獨游戲是比較復雜的,首先要學會VBA編程。

⑸ 學數獨好呢!還是編程好

數獨是學習解決問題的思路,編程是學習賴以生存的手段。
只會編程不會數獨可能人生少了點什麼但不會混不下去,只會數獨不會編程可能連吃飽都是個問題。

⑹ 81格的九宮格,用c語言編程,求助

#include"stdio.h"
//定義棧的最大長度
#defineMAXSTACKLENGTH81
//待求解的九宮格矩陣,空白位置用0表示
intjiuGongArray[][9]={{0,0,0,0,4,0,0,3,2},
{4,0,0,0,0,1,0,0,0},
{5,3,0,6,0,0,0,0,7},
{3,0,0,5,1,0,7,0,0},
{0,0,5,0,3,0,2,0,0},
{0,0,9,0,7,4,0,0,3},
{1,0,0,0,0,9,0,4,6},
{0,0,0,1,0,0,0,0,9},
{8,9,0,0,6,0,0,0,0}};
//空缺數據組成的矩陣,共有九個九宮格單元,從左到右,然後從上到下編號為0-8;
//例如:第一個九宮格單元空缺的數字為1,4,8,則矩陣dataNeedToBeInsert的第一行
//為{1,0,0,4,0,0,0,8,0}
intdataNeedToBeInsert[][9]={{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9}};
//定義棧單元的結構
typedefstruct
{
intxPosition;
intyPosition;
intjiuGongGePosition;
intnum;
}node;
//定義棧數組
nodestack[MAXSTACKLENGTH];
//由給定的九宮格矩陣,查找空缺的數據
voidFindDataToBeInsert(void)
{
inti,j;
intx,y;
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{
if(jiuGongArray[i][j]!=0)
{
x=(i/3)*3+j/3;
y=jiuGongArray[i][j]-1;
dataNeedToBeInsert[x][y]=0;
}
}
}
//輸出m*n的矩陣
voidPrintArray(int*ptr,intm,intn)
{
inti,j;
intdata;
inttemp;
temp=n-1;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
data=*(ptr+i*n+j);
printf("%d",data);
if(j==temp)
{
printf(" ");
}
}
}
//核實是否滿足結束條件
intCheckEnd(void)
{
inti,j,sum;
for(i=0;i<9;i++)
{
sum=0;
for(j=0;j<9;j++)
{
sum+=jiuGongArray[i][j];
}
if(sum!=45)
{
return-1;
}
}
for(j=0;j<9;j++)
{
sum=0;
for(i=0;i<9;i++)
{
sum+=jiuGongArray[i][j];
}
if(sum!=45)
{
return-1;
}
}
return0;
}
//從矩陣dataNeedToBeInsert[][]中查找下一個數據
intFindNextData(intm,intn,int*xPosition,int*yPosition)
{
intstate=0;
if(n>8)
{
n=0;
m++;
}
if(m>8)
{
state=CheckEnd();
if(state!=0)
return-1;
else
return1;
}
while(dataNeedToBeInsert[m][n]==0)
{
if(n<8)
n++;
else
{
n=0;
m++;
if(m>8)
{
state=CheckEnd();
if(state!=0)
return-1;
else
return1;
}
}
}
*xPosition=m;
*yPosition=n;
return0;
}
//核實元素對應的行和列是否有相同的數字
intCheckLine(intm,intn,intnum)
{
inti;
for(i=0;i<9;i++)
{
if(jiuGongArray[m][i]==num)
return-1;
}
for(i=0;i<9;i++)
{
if(jiuGongArray[i][n]==num)
return-1;
}
return0;
}
//核實是否滿足入棧條件
intCheckCanPush(intm,intn,int*position)
{
intstart=*position;
inti,temp1,temp2,temp3,temp4;
intnum;

temp1=(m/3)*3;
temp2=(m%3)*3;
num=dataNeedToBeInsert[m][n];

for(i=start;i<10;i++)
{
temp3=temp1+(start-1)/3;
temp4=temp2+(start-1)%3;

if(jiuGongArray[temp3][temp4]!=0)
{
start++;
continue;
}
if(CheckLine(temp3,temp4,num)!=0)
{
start++;
continue;
}
else
{
*position=start;
return0;
}
}

return-1;
}
//入棧
intPush(int*top,intxPosition,intyPosition,intjiuGongGePosition,intnum)
{
if(*top>=MAXSTACKLENGTH)
{
printf("Reachstacktop! ");
return-1;
}
else
{
(*top)++;
stack[*top].xPosition=xPosition;
stack[*top].yPosition=yPosition;
stack[*top].jiuGongGePosition=jiuGongGePosition;
stack[*top].num=num;
return0;
}
}
//出棧
intPop(int*top,int*xPosition,int*yPosition,int*jiuGongGePosition,int*num)
{
if(*top==-1)
{
printf("Reachstackbottom! ");
return-1;
}
else
{
*xPosition=stack[*top].xPosition;
*yPosition=stack[*top].yPosition;
*jiuGongGePosition=stack[*top].jiuGongGePosition;
*num=stack[*top].num;
(*top)--;
return0;
}
}
voidmain()
{
intend=0;
intline=0;
introw=0;
inttop=-1;
intpositionInUnitArray=1;
intstate=0;
intnum;

FindDataToBeInsert();

PrintArray(jiuGongArray,9,9);
while(end!=1)
{
state=FindNextData(line,row,&line,&row);
if(state==0)
{
state=CheckCanPush(line,row,&positionInUnitArray);
if(state==0)
{
state=Push(&top,line,row,positionInUnitArray,dataNeedToBeInsert[line][row]);
if(state==0)
{
jiuGongArray[(line/3)*3+(positionInUnitArray-1)/3][(line%3)*3+(positionInUnitArray-1)%3]=dataNeedToBeInsert[line][row];
row++;
positionInUnitArray=1;
}
else
end=1;
}
else
{
state=Pop(&top,&line,&row,&positionInUnitArray,&num);
if(state==0)
{
jiuGongArray[(line/3)*3+(positionInUnitArray-1)/3][(line%3)*3+(positionInUnitArray-1)%3]=0;
positionInUnitArray++;
}
else
end=1;
}
}
elseif(state==1)
{
printf(" ");
PrintArray(jiuGongArray,9,9);
end=1;
}
else
{
printf("Someerroroccur! ");
end=1;
}
}
}

⑺ 如何用pascal編程解「數獨」

這是個好問題,我也想知道,我想樓主是不是把帖子發的編程那邊。

⑻ 數獨演算法

給你數獨計算器:
http://blog.xunlei.com/web/category.html?uin=mianmiany1978&category_id=143
數獨游戲:
http://blog.xunlei.com/web/category.html?uin=mianmiany1978&category_id=174
數獨演算法:
http://www.puzzle8.com/suku/news.asp
數獨快速入門(上篇)
數獨快速入門(中篇)
數獨快速入門(下篇)
唯一解法
唯一候選數法
隱性三鏈數刪減法
隱性數對刪減法
三鏈列刪減法
區塊刪減法
矩形頂點刪減法
關鍵數刪減法

補充:
合格的數獨是只有唯一解。
而數獨有難易度的分類,找一份報紙注意刊登的數獨謎題是1星,還是5星。
在網路上,更分成容易題、進階題、難題、極難題、超難題....
一般都是依據需要運用的技巧,而技巧是區分難易的。

數獨不用猜測,解題全部是運用邏輯推理。
數獨不用電腦程序分析,就可以解的題目是直觀法數獨題。
而超難題是需要電腦分析,及把全盤標示可選數,那是可選數謎題。
沒有所謂解題通則。

1.直觀解(一般報紙、書籍)
直觀法技巧
直觀法技巧 01 (容易級) 唯一解
直觀法技巧 02 (容易級) 基本摒除
直觀法技巧 03 (進階級) 宮對行列摒除
直觀法技巧 04 (進階級) 行列對宮摒除
直觀法技巧 05 (進階級) 群組解法
直觀法技巧 06 (困難級) X-Wing摒除法01
直觀法技巧 06 (困難級) X-Wing摒除法02
直觀法技巧 07 (困難級) 數偶摒除法

http://hi..com/kiwy07/blog/item/181fc482a153f3bd6c8119ab.html

2.可選數(以程序自動生成可選數)

Last value in block, row or column
Hidden Single in block
Hidden Single in row or column
Direct Pointing
Direct Claiming
Direct Hidden Pair
Naked Single
Direct Hidden Triplet
Pointing
Claiming
Naked Pair, X-Wing, Hidden Pair
Naked Triplet, Swordfish, Hidden Triplet
XY-Wing, XYZ-Wing
Unique rectangles and loops
Naked Quad, Jellyfish, Hidden Quad
Bivalue Universal Graves
Aligned Pair Exclusion
Bidirectioal X-Cycles and Y-Cycles
Forcing X-Chains
Forcing Chains, Bidirectional Cycles
Nishio
Cell/Region Forcing Chains
Dynamic Forcing Chains

http://diuf.unifr.ch/people/juillera/Sudoku/FAQ.html

通則無法解的題
直觀難題
006589307
030602008
809703500
000891403
394265871
180374000
003026785
000458030
008037200
可選數極難題
970000000
003927000
008410709
300700400
060050070
007040003
105074900
000068507
786000042
不要把謎題解一次列出,而是找出下一步,及他的邏輯推理方法。
不要用猜測。

熱點內容
手機優酷緩存視頻格式 發布:2025-05-15 04:13:45 瀏覽:208
公益電影分鏡頭腳本插畫 發布:2025-05-15 04:08:37 瀏覽:959
數據壓縮編碼 發布:2025-05-15 03:58:44 瀏覽:725
java字元為空 發布:2025-05-15 03:57:11 瀏覽:546
速訊安卓哪裡下載 發布:2025-05-15 03:55:02 瀏覽:48
緩存區數據讀寫原理 發布:2025-05-15 03:39:57 瀏覽:585
編譯器生成的是二進制文件嗎 發布:2025-05-15 03:38:42 瀏覽:955
運營為什麼區分ios和安卓 發布:2025-05-15 03:30:02 瀏覽:630
主播網站源碼 發布:2025-05-15 02:50:56 瀏覽:168
中文編程語言有哪些 發布:2025-05-15 02:48:59 瀏覽:536