收藏 分销(赏)

智力拼图问题.doc

上传人:s4****5z 文档编号:8891113 上传时间:2025-03-06 格式:DOC 页数:9 大小:42.50KB 下载积分:10 金币
下载 相关 举报
智力拼图问题.doc_第1页
第1页 / 共9页
智力拼图问题.doc_第2页
第2页 / 共9页


点击查看更多>>
资源描述
/* 智力拼图问题:将一个6*8的矩阵模块,划分成n个小模块,设计一个算法,用这n个小模块再重新拼接成原 6*8矩阵,要求给出所有的可行方案。 本函数是演示程序,程序最多可以将6*8大小的矩阵分成15个模块,每个小模块的大小不能超过4*4大。并允许 手动编辑。该程序计算所有的可行方案并显示出组合拼接的所有结果。本程序在初始的时候已经给了一个11模块的划分形式,要演示按回车即可。 backup函数是本程序的核心函数,该函数采用标准的递归回溯算法,算法的基本思想是: 从左到右,从上到下扫描6*8矩阵,如果发现某个位置为空(用0表示)就依次尝试每一个还没有用到的 小模块,如果该小模块可以安放在这个位置,那么就放置上去并递归调用下一个可行的位置,否则如果所有小 模块用尽,那么就产生回溯。该函数有两个主要参数x0,y0,表示在6*8矩阵中的第一个空位置。 本程序的操作方法为: 回车:演示开始。 q:在演示过程中退出演示进入模块编辑模式。 c:在编辑模式中减少一个编辑值。 v:在编辑模式中增加一个编辑值。 空格:用于在光标出设置该编辑值。 上,下,左,右:移动光标。 ESC:在编辑模式下退出程序。 如果想让本程序独立运行即其exe文件可以脱离tc根目录到其他目录下运行,要进行如下操作:     在tc根目录下键入:     c:\turboc2>bgiobj egavga  //bgiobj是tc下的命令,它将egavga.bgi转换成egavga.obj的目标文件     c:\turboc2>tlib lib\graphics.lib+egavga  //tlib将egavga.obj的目标模块装到graphics.lib库中 最后在本程序的opengraph函数中加入registerbgidriver(EGAVGA_driver);语句 本程序采用了很好的算法思想,有很高的阅读价值和参考价值,但并不适合c语言初学者, 特别是那些还没有学过数据结构的同学。 本程序建议在vc++6.0下打开阅读,在tc2.0下编译链接 */ #include <stdio.h> #include <stdlib.h> #include <bios.h> #include <graphics.h> #include <string.h> /*以下定义键盘扫描码*/ #define  k_enter 7181 #define  k_up    18432 #define  k_down  20480 #define  k_left  19200 #define  k_right 19712 #define  k_space 14624 #define  k_esc   283 #define  k_c    11875 #define  k_q    4209 #define  k_v    12150 #define _ROW 6 #define _COL 8 #define _MDLM  25   #define _MDLN  25 #define FLASH  2   /*光标闪烁间隔时间*/ typedef struct point  { int x; int y; }point; int Qmat[_ROW][_COL];     /*该数组用于存储原始数据_ROW=6,_COL=8*/ int Qmatd[_ROW][_COL];    /*该数组保存运行时结果*/ int shapep[16][17][2];    /*该数组用于保存每个小模块的形状*/ static int Initmat[_ROW][_COL]={1,1,2,2,7,7,10,11,/*该数组保存初始的设置值*/     1,1,2,2,7,7,10,10,        1,1,3,3,7,8,9,10,        3,3,3,3,6,8, 9,10,        4,4,4,5,6,8,9,9,        4,4,4,5,6,8,9,9}; int f_num[16];       /*该函数用于记录每个小模块的数组元素组成个数*/ void opengraph(void);  /*打开图形模式*/ void delayx(int);     /*精确延时函数*/ void Init(void);       /*对相关数据结构进行初始化*/ int  DispModule(void);    /*显示所有的小模块形状并计算相关数据结构值*/ void OutputMessage(char* str);   /*在屏幕特定位置显示一行信息str*/ void dispcnum(int num);   /*在屏幕特定位置显示一个数值num*/ void backup(int x0,int y0,int* f_exit);   /*完成对问题的回溯求解*/ main()  { int flag_f=1,f_flash=0,f_putok=1,f_b=1; int i=0,j=0,keyid; int ix,jx; int fnum=1; char strn[5];     opengraph();     Init();     setcolor(WHITE); settextstyle(0,0,1); dispcnum(fnum); while(flag_f)   {  /*flag_f状态循环*/   if(bioskey(1))  {   /*如果有键按下*/    keyid=bioskey(0);    /*读取键值*/    if(keyid==k_up||keyid==k_down||keyid==k_left||keyid==k_right)  {     setfillstyle(SOLID_FILL,BLACK);   /*重显示光标下隐藏数字*/     setcolor(WHITE);     bar(_MDLN*(j+1)+4,_MDLM*(i+1)+4,_MDLN*(j+2)-4,_MDLM*(i+2)-4);     itoa(Qmat[i][j],strn,10);     outtextxy(_MDLN*(j+1)+6,_MDLM*(i+1)+_MDLM/2,strn);    }    switch(keyid)  {    case k_up:     i=i==0?i:i-1;     break;    case k_down:     i=i+1==_ROW?i:i+1;     break;             case k_left:     j=j==0?j:j-1;     break;    case k_right:     j=j+1==_COL?j:j+1;     break;    case k_esc:                 flag_f=0;     break;    case k_v:     if(fnum<15) ++fnum;     dispcnum(fnum);     break;    case k_c:     if(fnum>1) --fnum;     dispcnum(fnum);     break;    case k_space:       Qmat[i][j]=fnum;                 itoa(fnum,strn,10);     setcolor(WHITE);     outtextxy(_MDLN*(j+1)+6,_MDLM*(i+1)+_MDLM/2,strn);     if((f_putok=DispModule())<=0)  OutputMessage("Module Error!");     else OutputMessage("Module must less than 4x4!");     break;    case k_enter:           if(f_putok>0)  {/*f_putok>0表示模块拆分的合理(小于4*4)*/               f_b=1;      backup(0,0,&f_b);   /*计算所有可行方案*/      OutputMessage("That's all! Anykey to return!");      getch();      setcolor(WHITE);      settextstyle(0,0,1);      setfillstyle(SOLID_FILL,BLACK);      for(ix=0;ix<_ROW;ix++)  {                   for(jx=0;jx<_COL;jx++)  {        bar(_MDLN*(jx+1)+4,_MDLM*(ix+1)+4,_MDLN*(jx+2)-4,_MDLM*(ix+2)-4);                    itoa(Qmat[ix][jx],strn,10);                       outtextxy(_MDLN*(jx+1)+6,_MDLM*(ix+1)+_MDLM/2,strn);       }      }      OutputMessage("Module must less than 4x4!");     }     break;    }   }   delayx(FLASH);     if(f_flash)  {   /*用于在编辑模式下完成光标的闪烁*/    f_flash=0;    setcolor(WHITE);    setfillstyle(SOLID_FILL,BLACK);    bar(_MDLN*(j+1)+4,_MDLM*(i+1)+4,_MDLN*(j+2)-4,_MDLM*(i+2)-4);    itoa(Qmat[i][j],strn,10);    outtextxy(_MDLN*(j+1)+6,_MDLM*(i+1)+_MDLM/2,strn);   }   else  {    f_flash=1;    setfillstyle(SOLID_FILL,WHITE);    bar(_MDLN*(j+1)+4,_MDLM*(i+1)+4,_MDLN*(j+2)-4,_MDLM*(i+2)-4);   } } closegraph(); } void dispcnum(int num)  {     char strn[5];     setcolor(WHITE);     settextstyle(0,0,1);     setfillstyle(SOLID_FILL,BLACK);     bar(30,180,100,198);     itoa(num,strn,10);     outtextxy(30,185,strn); } void backup(int x0,int y0,int* f_exit)  {/*递归函数*/     int i,j,f_ok,x,y; char strn[5];     for(i=1;i<16;i++)  if(f_num[i]>0)  break; if(x0>=_ROW||y0>=_COL||i==16)  {  /*i==16表示所有模块都以用完,这样就得到了一个可行方案*/   setcolor(BLACK);   settextstyle(0,0,1);      for(i=0;i<_ROW;i++)  {       for(j=0;j<_COL;j++)  {     setfillstyle(SOLID_FILL,Qmatd[i][j]);        bar(_MDLN*(j+1)+4,_MDLM*(i+1)+4,_MDLN*(j+2)-4,_MDLM*(i+2)-4);        itoa(Qmatd[i][j],strn,10);           outtextxy(_MDLN*(j+1)+6,_MDLM*(i+1)+_MDLM/2,strn);    }   }   OutputMessage("Anykey to continue,q to Quit!");   if(getch()=='q') *f_exit=0;  /*如果按下'q'则强行退出递归*/   return; } for(i=1;i<16&&*f_exit;i++)  {/*计算每一个可用的模块*/   if(f_num[i]>0)  {  /*如果未用*/    f_ok=1;    x=x0;  y=y0;    for(j=1;j<=f_num[i]&&f_ok;j++)  {  /*完成对该模块的放置并检查可行性*/     if(x>=0&&y>=0&&x<_ROW&&y<_COL&&Qmatd[x][y]==0) Qmatd[x][y]=i;     else  {      f_ok=0;                     for(x=0;x<_ROW;x++)                     for(y=0;y<_COL;y++)                         if(Qmatd[x][y]==i)  Qmatd[x][y]=0;     }                 x=x0+shapep[i][j][0]; /*又偏移得到组成模块的下一个位置*/        y=y0+shapep[i][j][1];    }    if(f_ok)  {  /*如果放置成功则继续递归,否则回溯*/                 f_num[i]=0-f_num[i];   /*求负表示该模块以用*/     for(x=0;x<_ROW&&f_ok;x++)  /*找到第一个可空位置*/                 for(y=0;y<_COL&&f_ok;y++)        if(Qmatd[x][y]==0)  f_ok=0;           backup(x-1,y-1,f_exit);  /*对该空位置产生递归调用*/     for(x=0;x<_ROW;x++)     /*恢复数组数据*/                 for(y=0;y<_COL;y++)      if(Qmatd[x][y]==i)  Qmatd[x][y]=0;                 f_num[i]=0-f_num[i];   /*恢复*/    }   } } } void Init(void)  { int i,j; char strn[5]; setcolor(WHITE); settextstyle(0,0,1); outtextxy(_MDLN,_MDLN/2,"QiQiaoBan question by STN_LCD!I love doudou!"); for(i=0;i<_ROW;i++)  {   for(j=0;j<_COL;j++)  {       setcolor(YELLOW);    rectangle(_MDLN*(j+1),_MDLM*(i+1),_MDLN*(j+2),_MDLM*(i+2));    Qmat[i][j]=Initmat[i][j];    Qmatd[i][j]=0;    itoa(Qmat[i][j],strn,10);             setcolor(WHITE);       outtextxy(_MDLN*(j+1)+6,_MDLM*(i+1)+_MDLM/2,strn);   } } OutputMessage("Module must less than 4x4 !"); DispModule(); } void OutputMessage(char* str)  {     setfillstyle(SOLID_FILL,BLACK); bar(250,50,630,80); setcolor(WHITE); settextstyle(0,0,1); outtextxy(252,60,str); } int DispModule(void) {     int dispnum=0,flag,ip_sharp; int Qmatnum; int i,j,ik,jk,x,y,in,jn; char strn[5];     memset(f_num,0,16*sizeof(int)); for(i=0;i<_ROW;i++)   for(j=0;j<_COL;j++)    ++f_num[Qmat[i][j]]; setfillstyle(SOLID_FILL,BLACK); bar(20,200,600,450); for(dispnum=1;dispnum<=15;dispnum++)  {   if(f_num[dispnum])  {    flag=1;    for(i=0;i<=2&&flag;i++)  {     for(j=0;j<=4&&flag;j++)  {      Qmatnum=0;      for(ik=i;ik<i+4;ik++)        for(jk=j;jk<j+4;jk++)           if(Qmat[ik][jk]==dispnum)  ++Qmatnum;                     if(Qmatnum==f_num[dispnum])  {                         flag=0;       x=(dispnum-1)%5; y=(dispnum-1)/5;             x=20+80*x; y=200+80*y;       setcolor(WHITE);       rectangle(x,y,x+80,y+80);             ip_sharp=0;                for(in=0,ik=i;ik<i+4;ik++,in++)  {              for(jn=0,jk=j;jk<j+4;jk++,jn++)  {         if(Qmat[ik][jk]==dispnum)  {          if(ip_sharp==0)  {           shapep[dispnum][ip_sharp][0]=ik;           shapep[dispnum][ip_sharp++][1]=jk;          }          else  {                                         shapep[dispnum][ip_sharp][0]=ik-shapep[dispnum][0][0];           shapep[dispnum][ip_sharp++][1]=jk-shapep[dispnum][0][1];          }          setcolor(BLACK);          setfillstyle(SOLID_FILL,Qmat[ik][jk]);                   bar(x+20*jn+2,y+20*in+2,x+20*(jn+1)-2,y+20*(in+1)-2);          itoa(Qmat[ik][jk],strn,10);                   outtextxy(x+20*jn+3,y+20*in+5,strn);         }        }       }      }     }    }    if(flag)  return 0;   } } return 1; } void opengraph(void)  { int gdriver=VGA,gmode=VGAHI; /*registerbgidriver(EGAVGA_driver);*/     initgraph(&gdriver,&gmode,""); } void delayx(int clicks)  { unsigned int far *clock=(unsigned int far*)0x0000046cL; unsigned int now; now=*clock; while(abs(*clock-now)<clicks){} }  [upload=rar]viewFile.asp
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服