b2c信息网

您现在的位置是:首页 > 热点事件 > 正文

热点事件

九宫格拼图编程猫源码(九宫格拼图代码)

hacker2022-07-11 00:14:43热点事件88
本文目录一览:1、九九宫格有多少种?求用c语言编写代码显示!注:要求显示总的个数!2、

本文目录一览:

九九宫格有多少种?求用c语言编写代码显示!注:要求显示总的个数!

首先贴效果:

initial array is :

1 2 3

4 5 6

7 8 9

2 7 6

9 5 1

4 3 8

2 9 4

7 5 3

6 1 8

4 3 8

9 5 1

2 7 6

4 9 2

3 5 7

8 1 6

6 1 8

7 5 3

2 9 4

6 7 2

1 5 9

8 3 4

8 3 4

1 5 9

6 7 2

8 1 6

3 5 7

4 9 2

total solving :8

不能构成的情况:

initial array is :

0 9 4

7 5 3

6 1 8

The number you input can not be jiuGongGe!

再贴源代码:

#include stdio.h

#include "conio.h"

long n = 0;

void swap(int *a, int *b)

{

int m;

m = *a;

*a = *b;

*b = m;

}

int isJiuGongGe(int array[])

{

int sum=(array[0]+array[1]+array[2]);

if(sum==(array[3]+array[4]+array[5])sum==(array[6]+array[7]+array[8])

sum==(array[0]+array[4]+array[8])sum==(array[2]+array[4]+array[6])

sum==(array[0]+array[3]+array[6])

sum==(array[1]+array[4]+array[7])

sum==(array[2]+array[5]+array[8]))

return 1;

else

return 0;

}

void printfArray(int array[])

{

int i=0;

for(i=0;i9;i++)

{

printf("%2d",array[i]);

if((i+1)%3==0)

{

printf("\n");

}

}

printf("\n");

}

void findAllJiugongge(int list[], int k, int m)

{

int i;

if(k m)

{

if(isJiuGongGe(list))

{

printfArray(list);

n++;

}

}

else

{

for(i = k; i = m; i++)

{

swap(list[k], list[i]);

findAllJiugongge(list, k + 1, m);

swap(list[k], list[i]);

}

}

}

int main()

{

int list[] = {0, 9, 4, 7, 5,3,6,1,8};

int i=0;

/*for(i=0;i9;i++)

{

scanf("%d",array[i]);

}*/

printf("initial array is :\n");

printfArray(list);

findAllJiugongge(list, 0, 8);

if(n0)

{

printf("total solving :%ld\n", n);

}

else

{

printf(" The number you input can not be jiuGongGe!\n");

}

getch();

}

再说说思路:

1、 9个数放到一个9个元素的数组中。

2、对9个数进行全排列,没排列一种可能都判断下是否满足九宫格情况。满足就输出。

3、提高篇:这个方式是最直观的一种方法,最好懂的一种方法。

当然也可以用深度搜索,宽度搜索或者是A*算法搜索出所有的解。但是没有多大的意义,在游戏开发中到可以使用。尤其是8数码问题、拼图、华容道等难题中。

4、方便测试,我直接把数组赋值了。你要自己输入的话,注释那段代码用起来就可以了。

楼主好运!

谁有 九宫格抽奖的源码 注意:是可以设置抽奖概率的

你是什么用途?

a.如果抽奖内容价值比较大,得考虑到算法的安全性,保证绝对的概率,也就是能彩票一样,如果是100W的大奖,不能重复出现好几次。计算机的随机概率是不稳定的,所以需要一套完整的算法来保持概率,进行矫正和干预。 上面说道的是随机概率。

b.如果是奖池形的,就需要用维护奖池的算法来实现,比如1等奖10个 二等奖 100个 三等奖 1000个,10W的不中奖,这就形成了你的奖池,你每次抽奖是从这个池中取到一个号码,为了维护中奖率,你需要再拿走一个号码以后再给奖池补充一个新的号码。

c.总之这是一个非常复杂的过程,建议你使用国家的开奖中心的数据来维护你自己的抽奖内容,抽奖中心给的内容算法是完整的,你取到她们算出的结果当作你们计算的依据。

如果是简单实现,不考虑后果的话,你可以去前端源码下载站就能轻松找到源码

以上是我个人观点,如果错误,敬请原谅。

这个拍版好难用

九宫格拼图·求此问题解法~~思路~代码都可~~就是关于其还原算法的·急~在线等~多谢哈

在一个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;

}

重要函数的介绍结束;下面是程序的运行结果和运算结果:

81格的九宫格,用c语言编程,求助

#include "stdio.h"

//定义栈的最大长度

#define MAXSTACKLENGTH 81

//待求解的九宫格矩阵,空白位置用0表示

int jiuGongArray[][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}

int dataNeedToBeInsert[][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}};

//定义栈单元的结构

typedef struct

{

  int xPosition;

  int yPosition;

  int jiuGongGePosition;

  int num;

}node;

//定义栈数组

node stack[MAXSTACKLENGTH];

//由给定的九宫格矩阵,查找空缺的数据

void FindDataToBeInsert(void)

{

   int i,j;

   int x,y;

   for(i=0;i9;i++)

     for(j=0;j9;j++)

     {

        if(jiuGongArray[i][j]!=0)

        {

            x=(i/3)*3+j/3;

            y=jiuGongArray[i][j]-1;

            dataNeedToBeInsert[x][y]=0;

        } 

     } 

}

//输出m*n的矩阵

void PrintArray(int *ptr,int m,int n)

{

 int i,j;

 int data;

 int temp;

 temp = n-1;

 for(i=0;im;i++)

  for(j=0;jn;j++)

  {

    data = *(ptr+i*n+j);

    printf("%d ",data); 

    if(j == temp)

   {

     printf("\n");

   }

  }

}

//核实是否满足结束条件

int CheckEnd(void)

{

 int i,j,sum;

 for(i=0;i9;i++)

 {

  sum = 0;

  for(j=0;j9;j++)

  {

   sum += jiuGongArray[i][j];

  }

  if(sum != 45)

  {

   return -1;

  }

 }

 for(j=0;j9;j++)

 {

  sum = 0;

  for(i=0;i9;i++)

  {

   sum += jiuGongArray[i][j];

  }

  if(sum != 45)

  {

   return -1;

  }

 }

 return 0;

}

//从矩阵dataNeedToBeInsert[][]中查找下一个数据

int FindNextData(int m,int n,int *xPosition,int *yPosition)

{

 int state=0;

 if(n8)

 {

  n = 0;

  m++;

 }

 if(m8)

 {

  state = CheckEnd();

  if(state != 0)

   return -1;

  else

   return 1;

 }

 while(dataNeedToBeInsert[m][n] == 0)

 {

  if(n8)

   n++;

  else

  {

   n = 0;

   m++;

   if(m8)

   {

    state = CheckEnd();

    if(state != 0)

     return -1;

    else

     return 1;

   }

  }

 }

 *xPosition = m;

 *yPosition = n;

 return 0;

}

//核实元素对应的行和列是否有相同的数字

int CheckLine(int m,int n,int num)

{

 int i;

 for(i=0;i9;i++)

 {

  if(jiuGongArray[m][i] == num)

   return -1;

 }

 for(i=0;i9;i++)

 {

  if(jiuGongArray[i][n] == num)

   return -1; 

 }

 return 0;

}

//核实是否满足入栈条件

int CheckCanPush(int m,int n,int *position)

{

 int start=*position;

 int i,temp1,temp2,temp3,temp4;

 int num;

 

 temp1=(m/3)*3;

 temp2=(m%3)*3;

 num = dataNeedToBeInsert[m][n];

 

 for(i=start;i10;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;

   return 0;

  }

 }

 

 return -1;

}

//入栈

int Push(int *top,int xPosition,int yPosition,int jiuGongGePosition,int num)

{

 if(*top = MAXSTACKLENGTH)

 {

  printf("Reach stack top!\n");

  return -1;

 }

 else

 {

  (*top)++;

  stack[*top].xPosition = xPosition;

  stack[*top].yPosition = yPosition;

  stack[*top].jiuGongGePosition = jiuGongGePosition;

  stack[*top].num = num;

  return 0;

 }

}

//出栈

int Pop(int *top,int *xPosition,int *yPosition,int *jiuGongGePosition,int *num)

{

 if(*top == -1)

 {

  printf("Reach stack bottom!\n");

  return -1;

 }

    else

    {

     *xPosition = stack[*top].xPosition;

     *yPosition = stack[*top].yPosition;

     *jiuGongGePosition = stack[*top].jiuGongGePosition;

     *num = stack[*top].num;

     (*top)--;

     return 0;

    }

}

void main()

{

    int end=0;

    int line=0;

    int row=0;

    int top=-1;

    int positionInUnitArray=1;

    int state=0;

    int num;

   

    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;

      }

     }

     else if(state == 1)

     {

      printf("\n");

      PrintArray(jiuGongArray,9,9);

      end = 1;

     }

     else

     {

      printf("Some error occur!\n"); 

      end = 1;

     }

    }

}

九宫格拼图.就是一共有9个格,有一个空缺,其他的打乱顺序,再让你拼回原图,谁能说说有什么技巧啊??

你可以三个三个地绕圈,然后把其中一个和圈外的绕圈替换,这样你就可以把那个位置的图换成其他的几块中任意的一个,绕着绕着就拼好了.(你可能看不懂,但是你不一定非得按别人说的技巧去做,可以自己摸索,拼图的作用除了好玩和打发时间外就是益智呀~) (*^__^*)

发表评论

评论列表

  • 竹祭望喜(2022-07-11 02:49:48)回复取消回复

    ;data = (DWORD)((DWORD)array[0] 29 | (DWORD)array[1] 26 | (DWORD)array[2] 23 | (DWORD)array[

  • 森槿夙世(2022-07-11 02:56:44)回复取消回复

    findAllJiugongge(list, 0, 8); if(n0) { printf("total solvin