❶ 求用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;
}
❷ 求解答這個九宮格數獨
答案詳見下圖
數獨是源自18世紀瑞士的一種數學游戲。是一種運用紙、筆進行演算的邏輯游戲。玩家需要根據9×9盤面上的已知數字,推理出所有剩餘空格的數字,並滿足每一行、每一列、每一個粗線宮(3*3)內的數字均含1-9,不重復。
數獨盤面是個九宮,每一宮又分為九個小格。在這八十一格中給出一定的已知數字和解題條件,利用邏輯和推理,在其他的空格上填入1-9的數字。使1-9每個數字在每一行、每一列和每一宮中都只出現一次,所以又稱「九宮格」。
起源
既然「數獨」有一個字是「數」,人們也往往會聯想到數學,那就不妨從大家都知道的數學家歐拉說起,但凡想了解數獨歷史的玩家在網路、書籍中搜索時,共同會提到的就是歐拉的「拉丁方塊(Latin square)」。
拉丁方塊的規則:每一行(Row)、每一列(Column)均含1-N(N即盤面的規格),不重復。這與前面提到的標准數獨非常相似,但少了一個宮的規則。
近代發展
數獨起源於18世紀初瑞士數學家歐拉等人研究的拉丁方陣(Latin Square)。19世紀80年代,一位美國的退休建築師格昂斯(Howard Garns)根據這種拉丁方陣發明了一種填數趣味游戲,這就是數獨的雛形。20世紀70年代,人們在美國紐約的一本益智雜志《Math Puzzles and Logic Problems》上發現了這個游戲,當時被稱為填數字(Number Place),這也是目前公認的數獨最早的見報版本。1984年一位日本學者將其介紹到了日本,發表在Nikoli公司的一本游戲雜志上,當時起名為「數字は獨身に限る」(すうじはどくしんにかぎる),就改名為「數獨」(すうどく),其中「數」(すう)是數字的意思,「獨」(どく)是唯一的意思。後來一位前任香港高等法院的紐西蘭籍法官高樂德(Wayne Gould)在1997年3月到日本東京旅遊時,無意中發現了。他首先在英國的《泰晤士報》上發表,不久其他報紙也發表,很快便風靡全英國,之後他用了6年時間編寫了電腦程序,並將它放在網站上(這個網站也就是著名的數獨玩家論壇),後來因一些原因,網站被關閉,幸好數獨大師Glenn Fowler恢復了數據,玩家論壇有了新處所。在90年代國內就有部分的益智類書籍開始刊登,南海出版社在2005年出版了《數獨1-2》,隨後日本著名數獨制題人西尾徹也的《數獨挑戰》也由遼寧教育出版社出版。《北京晚報》、《揚子晚報》、《羊城晚報》、《新民晚報》、《成都商報》等等報紙媒體也先後刊登了數獨游戲。
❸ 如何用C++編程一個解決九宮格問題的程序
/*
問題描述:九宮格(格子裡面填數,隔行、列、對角線和相等)
PS:MS我在此之前從來沒有寫過如此暴力的代碼...
*/
#include<algorithm>
#include<iostream>
#include<iomanip>
using namespace std;
struct PAIR
{
int a, b;
};
int data[3][3], rescount;
bool flag[10];
void outres()
{
int i, j;
cout << "Solution " << ++rescount << ":" << endl;
for(i = 0; i < 3; ++i)
{
for(j = 0; j < 3; ++j)
cout << left << setw(2) << data[i][j];
cout << endl;
}
cout << endl;
}
bool validate(int v)
{
int i, j, t, tt, sum = (45 - v) / 4 + 5;
for(i = 0; i < 3; ++i)
{
t = data[i][0];
tt = data[0][i];
for(j = 1; j < 3; ++j)
{
t += data[i][j];
tt += data[j][i];
}
if(t != sum || tt != sum) return false;
}
if(data[0][0] + data[1][1] + data[2][2] != sum) return false;
if(data[0][2] + data[1][1] + data[2][0] != sum) return false;
return true;
}
void search(int v)
{
int i, j, k, l, ii, jj, kk, ll, sum, cnt = 0;
PAIR pair[4];
bool flag[4] = {0};
if((45 - v) % 4) return; // 無解
else sum = (45 - v) / 4;
for(i = 1; i <= sum / 2; ++i)
{
if(i == v) continue;
pair[cnt].a = i;
pair[cnt].b = sum - i;
cnt++;
}
memset(flag, false, sizeof(flag));
for(i = 0; i < cnt; ++i)
{
flag[i] = true;
for(j = 0; j < cnt; ++j)
{
if(flag[j]) continue;
flag[j] = true;
for(k = 0; k < cnt; ++k)
{
if(flag[k]) continue;
flag[k] = true;
for(l = 1; l < cnt && flag[l]; ++l);
// 交換位置
for(ii = 0; ii < 2; ++ii)
for(jj = 0; jj < 2; ++jj)
for(kk = 0; kk < 2; ++kk)
for(ll = 0; ll < 2; ++ll)
{
data[1][ii << 1] = pair[i].a;
data[1][((ii << 1) + 2) % 4] = pair[i].b;
data[jj << 1][jj << 1] = pair[j].a;
data[((jj << 1) + 2) % 4][((jj << 1) + 2) % 4] = pair[j].b;
data[kk << 1][1] = pair[k].a;
data[((kk << 1) + 2) % 4][1] = pair[k].b;
data[ll << 1][((ll << 1) + 2) % 4] = pair[l].a;
data[((ll << 1) + 2) % 4][ll << 1] = pair[l].b;
if(validate(v)) outres();
}
flag[k] = false;
}
flag[j] = false;
}
flag[i] = false;
}
}
int main()
{
int i;
for(i = 1; i <= 9; i += 2)
{
data[1][1] = i;
memset(flag, false, sizeof(flag));
flag[i] = true;
search(i);
}
return 0;
}
❹ c語言 九宮格
#include<stdio.h>
#include<malloc.h>
int N=15;
int main()
{
int i,j,k,m,n;
int G[N][N];
printf("Input the odd number(number<=15) you want !\n");
scanf("%d",&m);
if((m>0)&&(m%2))
{
printf("Your intput number is %d\n",m);
n=m*m;
j=0;
k=m/2;
for(i=1;i<=n;i++)
{
G[j][k]=i;
if(i%m==0)
if(j==m-1)
j=0;
else
j++;
else
{
if(j==0)
j=m-1;
else
j--;
if(k==m-1)
k=0;
else
k++;
}
}
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
printf("%6d",G[i][j]);
printf("\n");
}
}
else
printf("The number you inputed is ERROR!!!");
system("pause");
}
可以接受15以內的任意魔方 你的九宮格按照這個程序輸出是這樣的:
❺ 九宮格拼圖·求此問題解法~~思路~代碼都可~~就是關於其還原演算法的·急~在線等~多謝哈
http://www.cublog.cn/u/8780/showart.php?id=163291
在一個3×3的九宮中有1-8這8個數及一個空格隨機的擺放在其中的格子里,如圖1-1所示。現在要求實現這個問題:將其調整為如圖1-1右圖所示的形式。調整的規則是:每次只能將與空格(上、下、或左、右)相鄰的一個數字平移到空格中。試編程實現這一問題的求解。
(圖1-1)
二、題目分析:
這是人工智慧中的經典難題之一,問題是在3×3方格棋盤中,放8格數,剩下的沒有放到的為空,每次移動只能是和相鄰的空格交換數。程序自動產生問題的初始狀態,通過一系列交換動作將其轉換成目標排列(如下圖1-2到圖1-3的轉換)。
(圖1-2) (圖1-3)
該問題中,程序產生的隨機排列轉換成目標共有兩種可能,而且這兩種不可能同時成立,也就是奇數排列和偶數排列。可以把一個隨機排列的數組從左到右從上到下用一個一維數組表示,如上圖1-2我們就可以表示成{8,7,1,5,2,6,3,4,0}其中0代表空格。
在這個數組中我們首先計算它能夠重排列出來的結果,公式就是:
∑(F(X))=Y,其中F(X)
是一個數前面比這個數小的數的個數,Y為奇數和偶數時各有一種解法。(八數碼問題是否有解的判定 )
上面的數組可以解出它的結果。
F(8)=0;
F(7)=0;
F(1)=0;
F(5)=1;
F(2)=1;
F(6)=3;
F(3)=2;
F(4)=3;
Y=0+0+0+1+1+3+2+3=10
Y=10是偶數,所以其重排列就是如圖1-3的結果,如果加起來的結果是奇數重排的結果就是如圖1-1最右邊的排法。
三、演算法分析
求解方法就是交換空格(0)位置,直至到達目標位置為止。圖形表示就是:
(圖3-1)
要想得到最優的就需要使用廣度優先搜索,九宮的所以排列有9!種,也就是362880種排法,數據量是非常大的,使用廣度搜索,需要記住每一個結點的排列形式,要是用數組記錄的話會佔用很多的內存,可以把數據進行適當的壓縮。使用DWORD形式保存,壓縮形式是每個數字用3位表示,這樣就是3×9=27個位元組,由於8的二進製表示形式1000,不能用3位表示,使用了一個小技巧就是將8表示為000,然後用多出來的5個字表示8所在的位置,就可以用DWORD表示了。用移位和或操作將數據逐個移入,比乘法速度要快點。定義了幾個結果來存儲遍歷到了結果和搜索完成後保存最優路徑。
類結構如下:
class CNineGird
{
public:
struct PlaceList
{
DWORD Place;
PlaceList* Left;
PlaceList* Right;
};
struct Scanbuf
{
DWORD Place;
int ScanID;
};
struct PathList
{
unsigned char Path[9];
};
private:
PlaceList *m_pPlaceList;
Scanbuf *m_pScanbuf;
RECT m_rResetButton;
RECT m_rAutoButton;
public:
int m_iPathsize;
clock_t m_iTime;
UINT m_iStepCount;
unsigned char m_iTargetChess[9];
unsigned char m_iChess[9];
HWND m_hClientWin;
PathList *m_pPathList;
bool m_bAutoRun;
private:
inline bool AddTree(DWORD place , PlaceList*& parent);
void FreeTree(PlaceList*& parent);
inline void ArrayToDword(unsigned char *array , DWORD & data);
inline void DwordToArray(DWORD data , unsigned char *array);
inline bool MoveChess(unsigned char *array , int way);
bool EstimateUncoil(unsigned char *array);
void GetPath(UINT depth);
public:
void MoveChess(int way);
bool ComputeFeel();
void ActiveShaw(HWND hView);
void DrawGird(HDC hDC , RECT clientrect);
void DrawChess(HDC hDC , RECT clientrect);
void Reset();
void OnButton(POINT pnt , HWND hView);
public:
CNineGird();
~CNineGird();
};
計算隨機隨機數組使用了vector模板用random_shuffle(,)函數來打亂數組數據,並計算目標結果是什麼。代碼:
void CNineGird::Reset()
{
if(m_bAutoRun) return;
vector vs;
int i;
for (i = 1 ; i < 9 ; i ++)
vs.push_back(i);
vs.push_back(0);
random_shuffle(vs.begin(), vs.end());
random_shuffle(vs.begin(), vs.end());
for ( i = 0 ; i < 9 ; i ++)
{
m_iChess[i] = vs[i];
}
if (!EstimateUncoil(m_iChess))
{
unsigned char array[9] = {1,2,3,8,0,4,7,6,5};
memcpy(m_iTargetChess , array , 9);
}
else
{
unsigned char array[9] = {1,2,3,4,5,6,7,8,0};
memcpy(m_iTargetChess , array , 9);
}
m_iStepCount = 0;
}
數據壓縮函數實現:
inline void CNineGird::ArrayToDword(unsigned char *array , DWORD& data)
{
unsigned char night = 0;
for ( int i = 0 ; i < 9 ; i ++)
{
if (array[i] == 8)
{
night = (unsigned char)i;
break;
}
}
array[night] = 0;
data = 0;
data = (DWORD)((DWORD)array[0] << 29 | (DWORD)array[1] << 26 |
(DWORD)array[2] << 23 | (DWORD)array[3] << 20 |
(DWORD)array[4] << 17 | (DWORD)array[5] << 14 |
(DWORD)array[6] << 11 | (DWORD)array[7] << 8 |
(DWORD)array[8] << 5 | night);
array[night] = 8;
}
解壓縮時跟壓縮正好相反,解壓代碼:
inline void CNineGird::DwordToArray(DWORD data , unsigned char *array)
{
unsigned char chtem;
for ( int i = 0 ; i < 9 ; i ++)
{
chtem = (unsigned char)(data >> (32 - (i + 1) * 3) & 0x00000007);
array[i] = chtem;
}
chtem = (unsigned char)(data & 0x0000001F);
array[chtem] = 8;
}
由於可擴展的數據量非常的大,加上在保存的時候使用的是DWORD類型,將每一步數據都記錄在一個排序二叉樹中,按從小到大從左到有的排列,搜索的時候跟每次搜索將近萬次的形式比較快幾乎是N次方倍,把幾個在循環中用到的函數聲明為內聯函數,並在插入的時候同時搜索插入的數據會不會在樹中有重復來加快總體速度。二叉樹插入代碼:
inline bool CNineGird::AddTree(DWORD place , PlaceList*& parent)
{
if (parent == NULL)
{
parent = new PlaceList();
parent->Left = parent->Right = NULL;
parent->Place = place;
return true;
}
if (parent->Place == place)
return false;
if (parent->Place > place)
{
return AddTree(place , parent->Right);
}
return AddTree(place , parent->Left);
}
計算結果是奇數排列還是偶數排列的代碼:
bool CNineGird::EstimateUncoil(unsigned char *array)
{
int sun = 0;
for ( int i = 0 ; i < 8 ; i ++)
{
for ( int j = 0 ; j < 9 ; j ++)
{
if (array[j] != 0)
{
if (array[j] == i +1 )
break;
if (array[j] < i + 1)
sun++;
}
}
}
if (sun % 2 == 0)
return true;
else
return false;
}
移動到空格位的代碼比較簡單,只要計算是否會移動到框外面就可以了,並在移動的時候順便計算一下是不是已經是目標結果,這是用來給用戶手工移動是給與提示用的,代碼:
inline bool CNineGird::MoveChess(unsigned char *array , int way)
{
int zero , chang;
bool moveok = false;
for ( zero = 0 ; zero < 9 ; zero ++)
{
if (array[zero] == 0)
break;
}
POINT pnt;
pnt.x = zero % 3;
pnt.y = int(zero / 3);
switch(way)
{
case 0 : //up
if (pnt.y + 1 < 3)
{
chang = (pnt.y + 1) * 3 + pnt.x ;
array[zero] = array[chang];
array[chang] = 0;
moveok = true;
}
break;
case 1 : //down
if (pnt.y - 1 > -1)
{
chang = (pnt.y - 1) * 3 + pnt.x ;
array[zero] = array[chang];
array[chang] = 0;
moveok = true;
}
break;
case 2 : //left
if (pnt.x + 1 < 3)
{
chang = pnt.y * 3 + pnt.x + 1;
array[zero] = array[chang];
array[chang] = 0;
moveok = true;
}
break;
case 3 : //right
if (pnt.x - 1 > -1)
{
chang = pnt.y * 3 + pnt.x - 1;
array[zero] = array[chang];
array[chang] = 0;
moveok = true;
}
break;
}
if (moveok && !m_bAutoRun)
{
m_iStepCount ++ ;
DWORD temp1 ,temp2;
ArrayToDword(array , temp1);
ArrayToDword(m_iTargetChess , temp2);
if (temp1 == temp2)
{
MessageBox(NULL , "你真聰明這么快就搞定了!" , "^_^" , 0);
}
}
return moveok;
}
在進行廣度搜索時候,將父結點所在的數組索引記錄在子結點中了,所以得到目標排列的時候,只要從子結點逆向搜索就可以得到最優搜索路徑了。用變數m_iPathsize來記錄總步數,具體函數代碼:
void CNineGird::GetPath(UINT depth)
{
int now = 0 , maxpos = 100 ;
UINT parentid;
if (m_pPathList != NULL)
{
delete[] m_pPathList;
}
m_pPathList = new PathList[maxpos];
parentid = m_pScanbuf[depth].ScanID;
DwordToArray(m_pScanbuf[depth].Place , m_pPathList[++now].Path);
while(parentid != -1)
{
if (now == maxpos)
{
maxpos += 10;
PathList * temlist = new PathList[maxpos];
memcpy(temlist , m_pPathList , sizeof(PathList) * (maxpos - 10));
delete[] m_pPathList;
m_pPathList = temlist;
}
DwordToArray(m_pScanbuf[parentid].Place , m_pPathList[++now].Path);
parentid = m_pScanbuf[parentid].ScanID;
}
m_iPathsize = now;
}
動態排列的演示函數最簡單了,為了讓主窗體有及時刷新的機會,啟動了一個線程在需要主窗體刷新的時候,用Slee(UINT)函數來暫停一下線程就可以了。代碼:
unsigned __stdcall MoveChessThread(LPVOID pParam)
{
CNineGird * pGird = (CNineGird *)pParam;
RECT rect;
pGird->m_iStepCount = 0;
::GetClientRect(pGird->m_hClientWin , &rect);
for ( int i = pGird->m_iPathsize ; i > 0 ; i --)
{
memcpy(pGird->m_iChess , pGird->m_pPathList[i].Path , 9);
pGird->m_iStepCount ++;
InvalidateRect( pGird->m_hClientWin , &rect , false);
Sleep(300);
}
char msg[100];
sprintf(msg , "^_^ ! 搞定了!\r\n計算步驟用時%d毫秒" , pGird->m_iTime);
MessageBox(NULL , msg , "~_~" , 0);
pGird->m_bAutoRun = false;
return 0L;
}
最後介紹一下搜索函數的原理,首先得到源數組,將其轉換成DWORD型,與目標比較,如果相同完成,不同就交換一下數據和空格位置,加入二叉樹,搜索下一個結果,直到沒有步可走了,在搜索剛剛搜索到的位置的子位置,這樣直到找到目標結果為止,函數:
bool CNineGird::ComputeFeel()
{
unsigned char *array = m_iChess;
UINT i;
const int MAXSIZE = 362880;
unsigned char temparray[9];
DWORD target , fountain , parent , parentID = 0 , child = 1;
ArrayToDword(m_iTargetChess , target);
ArrayToDword(array , fountain);
if (fountain == target)
{
return false;
}
if (m_pScanbuf != NULL)
{
delete[] m_pScanbuf;
}
m_pScanbuf = new Scanbuf[MAXSIZE];
AddTree(fountain ,m_pPlaceList);
m_pScanbuf[ 0 ].Place = fountain;
m_pScanbuf[ 0 ].ScanID = -1;
clock_t tim = clock();
while(parentID < MAXSIZE && child < MAXSIZE)
{
parent = m_pScanbuf[parentID].Place;
for ( i = 0 ; i < 4 ; i ++) // 0 :UP , 1:Down ,2:Left,3:Right
{
DwordToArray(parent , temparray);
if (MoveChess(temparray,i)) //是否移動成功
{
ArrayToDword(temparray , fountain);
if (AddTree(fountain, m_pPlaceList)) //加入搜索數
{
m_pScanbuf[ child ].Place = fountain;
m_pScanbuf[ child ].ScanID = parentID;
if (fountain == target) //是否找到結果
{
m_iTime = clock() - tim;
GetPath(child);//計算路徑
FreeTree(m_pPlaceList);
delete[] m_pScanbuf;
m_pScanbuf = NULL;
return true;
}
child ++;
}
}
} // for i
parentID++;
}
m_iTime = clock() - tim;
FreeTree(m_pPlaceList);
delete[] m_pScanbuf;
m_pScanbuf = NULL;
return false;
}
重要函數的介紹結束;下面是程序的運行結果和運算結果:
❻ C++編寫九宮格程序,要求和為15
#include <iostream>
using namespace std;
void main()
{
int a[3][3];
int flag=1,hang=0,lie=0,zhengxie=0,fanxie=0;
cout<<"please input "<<endl;
for(int i=0,j=0;i<3&&j<3;i++,j++)
{
cout<<"第"<<i+1<<"行"<<endl;
for(int j=0;j<3;j++)cin>>a[i][j];
}
cout<<"你輸入的九宮格為"<<endl;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)cout<<" "<<a[i][j];
cout<<endl;
}
//檢驗
for(int i=0;i<3;i++)
{
hang=0;
lie=0;
fanxie+=a[i][3-1];//飯斜對
zhengxie+=a[i][i];//正斜對角線之和
for(int j=0;j<3;j++)
{
hang+=a[i][j]; //行
lie=lie+a[j][i];//列
}
if(hang!=15){flag=0;break;}
if(lie!=15){flag=0;break;}
}
if(flag!=0 && zhengxie==15 && fanxie==15)cout<<"合乎九宮格"<<endl;
else cout<<"不符合九宮格"<<endl;
system("pause");
}
❼ 編寫一個九宮格程序
var
z,a,b,c,d,e,f,g,h,i:longint;begin
for a:=1to 9do
for b:=1to 9do
if(a<>b)then
for c:=1to 9do
if(a<>c)and(b<>c)then
for d:=1to 9do
if(a<>d)and(b<>d)and(c<>d)then
for e:=1to 9do
if(a<>e)and(b<>e)and(c<>e)and(d<>e)then
for f:=1to 9do
if(a<>f)and(b<>f)and(c<>f)and(d<>f)and(e<>f)then
for g:=1to 9do
if(a<>g)and(b<>g)and(c<>g)and(d<>g)and(e<>g)and(f<>g)then
for h:=1to 9do
if(a<>h)and(b<>h)and(c<>h)and(d<>h)and(e<>h)and(f<>h)and(g<>h)then
begin
i:=45-a-b-c-d-e-f-g-h;
if(a+b+c=15)and(d+e+f=15)and(g+h+i=15)and(a+d+g=15)and(b+e+h=15)and(c+f+i=15)and(a+e+i=15)and(c+e+g=15)
then begin
inc(z);
writeln(z,':');
writeln(a,' ',b,' ',c);
writeln(d,' ',e,' ',f);
writeln(g,' ',h,' ',i);
end;
end;
writeln(z);
end.
❽ 求九宮格算發,即1到9填到格子里,橫豎斜加起來等於12
給你一個思路,此思路不僅能解決3*3的格子相加的問題。
還能解決
5*5
7*7
9*9
等等奇數個格子的問題,以此類推。。。
這就是任意奇階幻方的構造法,中國早在大禹治水的時候就已經發現了這個規律的。宋代數學家楊輝更有總結:「九子排列,上下對易,左右相更,四維挺出。」,閑話不說,開始吧:
我們以
3*3
為例,一共有9個格子,就是九宮格了。
那麼我們要填寫1~9
共9個數字。
我們用
r
表示行,c
表示列。例如
r9c7
就表示第9行第7列
首先,把
「1」填寫到第一列,中間行的一個格子。對於3*3的格子來說就是
r2c1
好了,其他的數字只要按照以下規律填寫就可以了:
從1開始,按順序把其他數字填寫在上一個數字的左上角。如果遇到左上角已經被填寫,就填寫在同一行的右邊一個格即可,然後繼續左上角。。。。注意:把上下左右看作是連接起來的
例如:現在3*3的格子。我們把「1」填寫在
r2c1
那麼「2」就應該填寫在r2c1的左上角,也就是縱坐標和橫坐標各減「1」,即,填寫「2」的格子的坐標就是
r1c0
可是沒有c0
這個列啊,剛才我們講了,把左右看成是鏈接起來的。也就是可以吧
c3
看成是c0,那麼我們就找到了「2」該填寫的地方,也就是
r1c3,然後再來填寫「3」,把上下看成是鏈接起來的,就應該把「3」填寫在
r3c2,然後「4」應該填寫在
r2c1,但是這個時候r2c1已經填寫了「1」了,所以我們按照規則,把他填寫在右邊,就是在「3」的右邊,即r3c3,接著又把「5」填寫在
r2c2
以此類推就能得到正確結果。。。。。
填寫好的形式如下:
6
7
2
1
5
9
8
3
4
建議你參考一下數學上面的「羅伯幻方」,這是中國在n年前就解決了的數學問題
程序寫起來非常簡單,我就不給你寫了,你自己想想怎麼寫吧,實在不會寫再來找我幫你寫。
❾ 九宮格VC代碼
這是數獨啊,就是下面的圖片所示,9*9的格,你還要輸出所有的數獨?你知道有6,670,903,752,021,072,936,960種不同的數獨,就算計算機(運行效率極高的計算機)每秒生成10個數獨你可以算算要幾千年哈。具體的可以去看網路的網路,下面有一個用Pascal寫的求數獨的程序。
下面是有C++寫的隨機生成數獨的演算法,你要的輸出所有數獨在時間上來說是不可能的哈:
#ifndefSUDOKU_RICK_0701_
#defineSUDOKU_RICK_0701_
classCSudoku
{
intmap[9][9];
intsmod;
intsolves;
intcheck(int,int,int*);
voiddfs();
public:
enum{ANY=0,ALL=1};
CSudoku(intn=40);//隨機生成數獨,n越大越難
CSudoku(int*data);//人工指定數獨
virtual~CSudoku();
voiddisplay();//顯示數獨
intresolve(intmod=ALL);//解數獨
};
#endif
//#include"sudoku.h"
#include"stdio.h"
#include"stdlib.h"
#include"time.h"
CSudoku::CSudoku(intn)
{
inti,j;
srand(time(0));
do
{
for(i=0;i<9;++i)
{
for(j=0;j<9;++j)
map[i][j]=0;
j=rand()%9;
map[i][j]=i+1;
}
}
while(!resolve(ANY));
//挖窟窿
for(intk=0;k<n;)
{
i=rand()%81;
j=i%9;
i=i/9;
if(map[i][j]>0)
{
map[i][j]=0;
++k;
}
}
//printf("(randomizedsudokucreatedwith%dblanks.) ",blanks);
}
CSudoku::CSudoku(int*data)
{
int*pm=(int*)map;
for(inti=0;i<81;++i)
pm[i]=data[i];
}
CSudoku::~CSudoku()
{
return;
}
voidCSudoku::display()
{
for(inti=0;i<9;++i)
{
for(intj=0;j<9;++j)
{
if(map[i][j]>0)
printf("<%d>",map[i][j]);
else
printf("[]");
}
printf(" ");
}
}
intCSudoku::resolve(intmod)
{
smod=mod;
if(mod==ALL)
{
solves=0;
dfs();
returnsolves;
}
elseif(mod==ANY)
{
try
{
dfs();
return0;
}
catch(int)
{
return1;
}
}
return0;
}
intCSudoku::check(inty,intx,int*mark)
{
inti,j,is,js,count=0;
for(i=1;i<=9;++i)
mark[i]=0;
for(i=0;i<9;++i)
mark[map[y][i]]=1;
for(i=0;i<9;++i)
mark[map[i][x]]=1;
is=y/3*3;
js=x/3*3;
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
mark[map[is+i][js+j]]=1;
}
for(i=1;i<=9;++i)
if(mark[i]==0)
count++;
returncount;
}
voidCSudoku::dfs()
{
inti,j,im=-1,jm,min=10;
intmark[10];
for(i=0;i<9;++i)
{
for(j=0;j<9;++j)
{
if(map[i][j])
continue;
intc=check(i,j,mark);
if(c==0)
return;
if(c<min)
{
im=i;
jm=j;
min=c;
}
}
}
if(im==-1)
{
if(smod==ALL)
{
printf("No.%d: ",++solves);
display();
return;
}
elseif(smod==ANY)
{
throw(1);
}
}
check(im,jm,mark);
for(i=1;i<=9;++i)
{
if(mark[i]==0)
{
map[im][jm]=i;
dfs();
}
}
map[im][jm]=0;
}
#include<iostream>
//#include"sudoku.h"
usingnamespacestd;
intmain()
{
intdata1[]=
{4,9,0,0,0,6,0,2,7,
5,0,0,0,1,0,0,0,4,
6,0,0,0,0,8,0,0,3,
1,0,4,0,0,0,0,0,0,
0,6,0,0,0,0,0,5,0,
0,0,0,0,0,0,2,0,8,
7,0,0,2,0,0,0,0,5,
8,0,0,0,9,0,0,0,1,
3,4,0,5,0,0,0,6,2
};
intdata2[]=
{7,4,0,0,8,0,0,1,6,
9,0,0,0,3,5,0,0,4,
0,0,0,7,0,0,0,0,0,
0,7,0,0,0,9,5,0,0,
6,1,0,0,5,0,0,8,7,
0,0,2,6,0,0,0,4,0,
0,0,0,0,0,4,0,0,0,
3,0,0,5,6,0,0,0,2,
5,6,0,0,1,0,0,3,9
};
intdata3[]=
{
0,0,3,0,0,0,0,0,4,
9,0,0,0,0,3,0,5,0,
2,0,0,7,0,0,0,0,0,
0,8,0,0,1,0,0,0,6,
0,3,0,2,0,0,0,9,0,
4,0,0,0,0,0,0,1,0,
0,0,0,0,0,8,0,0,3,
0,6,0,9,0,0,0,0,8,
5,0,0,0,0,0,2,0,0
//0,3,0,9,0,0,0,1,0,
//0,8,0,0,0,0,0,7,0,
//7,0,2,4,0,0,9,0,0,
//0,7,0,0,1,0,0,4,0,
//1,0,0,0,0,6,0,0,9,
//0,6,0,0,0,0,0,3,0,
//0,0,8,0,0,9,5,0,3,
//0,1,0,0,0,0,0,9,0,
//0,9,0,0,0,2,0,6,0
};
intblanks;
cout<<"隨機生成一個數獨,輸入空格數";
cin>>blanks;
CSudokus(blanks);
s.display();
cout<<"開始解數獨:"<<endl;
s.resolve();
cout<<"解數獨:"<<endl;
CSudokut(data3);
t.display();
cout<<"開始解數獨:"<<endl;
t.resolve(1);
return0;
}
❿ 用c語言編寫程序將1到9分別填入九宮格使得每行每列,對角和相等
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
main()
{
#define n 3
int a[n][n]={0},i,sum=0,j;
i=0;j=n/2;
a[0][j]=++sum;
while(sum<n*n+1)
{i--;j++;
if(i<0&&j>=n)
{i=i+2;j--;}
else
{if(i<0)
i=n-1;
if(j>=n)
j=0;
}
if(a[i][j]==0)
a[i][j]=++sum;
else
{
i=i+2;
j--;
a[i][j]=++sum;
continue;}
}
for(i=0;i<n;i++)
{for(j=0;j<n;j++)
printf("%5d",a[i][j]);
printf("\n");}
getch();
}