我的编程空间,编程开发者的网络收藏夹
学习永远不晚

用C++来解决3*3拼图的问题

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

用C++来解决3*3拼图的问题

解决3*3拼图的问题

拼图问题

在3*3的拼图中,如何用最少步骤拼好它,这个问题是一个最短路径问题,可以使用BFS来求解,每个节点是一个状态,然后得到最少步骤,中间状态可能需要对每一个状态进行编码或者散列记录才能输出,本代码只解决了求最短步数,其实利用一个栈是可以实现打印解题过程的。

代码

#include<bits/stdc++.h> 
using namespace std;

typedef int State[9];
const int maxstate=1000000;
State st[maxstate],goal;
int dist[maxstate];

const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
int vis[362880],fact[9];

void init_lookup_table(){
    fact[0]=1;
    for(int i=1;i<9;i++)    fact[i]=fact[i-1]*i;
}
int try_to_insert(int s){
    int code=0;
    for(int i=0;i<9;i++){
        int cnt=0;
        for(int j=i+1;j<9;j++)  if(st[s][j]<st[s][i])   cnt++;
        code+=fact[8-i]*cnt;
    }
    if(vis[code])   return 0;
    return vis[code]=1;
}
int bfs(){
    init_lookup_table();
    int front=1,rear=2;
    while(front<rear){
        State& s=st[front];
        if(memcmp(goal,s,sizeof(s))==0) return front;
        int z;
        for(z=0;z<9;z++)    if(!s[z])   break;
        int x=z/3, y=z%3;
        for(int d=0;d<4;d++){
            int newx=x+dx[d];
            int newy=y+dy[d];
            int newz=newx*3+newy;
            if(newx>=0&&newx<3&&newy>=0&&newy<3){
                State& t=st[rear];
                memcpy(&t,&s,sizeof(s));
                t[newz]=s[z];
                t[z]=s[newz];
                dist[rear]=dist[front]+1;
                if(try_to_insert(rear)) rear++;
            }
        }
        front++;
    }
    return 0;
}
int main(){
    freopen("F://inp.txt","r",stdin);
    for(int i=0;i<9;i++)    cin>>st[1][i];
    for(int i=0;i<9;i++)    cin>>goal[i];
    for(int i=0;i<9;i++){if(i&&i%3==0)  cout<<endl;cout<<st[1][i]<<" ";}
    int ans=bfs();
    if(ans>0)   printf("\nNeed %d steps come out!\n",dist[ans]);
    else    printf("\nNo way!\n");
    for(int i=0;i<9;i++){if(i&&i%3==0)  cout<<endl;cout<<goal[i]<<" ";}
    return 0;
}

纯C语言写的拼图游戏

大家好,刚才整理文件,找到了自己高三?高二?时候改编的拼图游戏,当然,因为c不支持图片,所以以数字1-8代替的,算法通用。。。

声明:

看图片,我放到网盘都3年了,里面自己改编了一半,算是半原创,算法作者找不到了、、、

以下正文

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
int MenuReturn;
void RandMap(char map[][3]);//随机生成数
void Game(void);//游戏主循环 
int Help(void);//游戏玩法介绍 
int About(void);
int        Menu(void);
void DealWithMenu(int MenuReturn); 
void Show(char map[][3]);
int IsWin(char map[][3]);//判断是否达成胜利条件 
int main(void)
{
        system("color 1E");
        while(1)
        {
                MenuReturn = Menu();
                DealWithMenu(MenuReturn);
        }
        return 0;
} 
int        Menu(void)
{
        int sel = 1;
        int tem = 0;
        char kb;
        system("cls");
        printf("  数字拼图      加q:1179307527\n\n\n");
        printf("->开始游戏<-\n  玩法介绍  \n  关    于  \n  退出游戏  \n");
        do{
                kb = getch();
                switch(kb)
                {
                        case 'w' : tem--;sel += tem;break;
                        case 's' : tem++;sel += tem; break;        
                        default  : NULL ; break;
                }
                tem = 0;
                if (sel == 0)
                {
                        sel = 4;
                }
                if (sel == 5)
                {
                        sel = 1;
                }
                system("cls");
                printf("  数字拼图\n\n\n");
                switch (sel)
                {
                        case 1 : printf("->开始游戏<-\n  玩法介绍  \n  关    于  \n  退出游戏  \n");break;
                        case 2 : printf("  开始游戏  \n->玩法介绍<-\n  关    于  \n  退出游戏  \n");break;
                        case 3 : printf("  开始游戏  \n  玩法介绍  \n->关    于<-\n  退出游戏  \n");break;
                        case 4 : printf("  开始游戏  \n  玩法介绍  \n  关    于  \n->退出游戏-<\n");break;
                        default: return-1; break; 
                }
        }while(kb != '\r');
 
        return sel;
}
void DealWithMenu(int MenuReturn)
{
        int retu;
        switch(MenuReturn)
        {
                case 1 : Game();break;
                case 2 : retu = Help();break;
                case 3 : retu = About();break;
                case 4 : exit(0);break;
                case -1: printf("发生未知错误!\n");        
        }
 
}
void Show(char map[][3])
{
        int i,j;
        system("cls");
        for(i=0;i<3;i++)
        {
                for(j=0;j<3;j++)
                {
                        printf("%2c",map[i][j]);
                }
                printf("\n");
        }
        
        return;
}
void MoveNumber(char map[][3],int *Crx,int *Cry)
{
        enum {UP,DOWN ,LEFT ,RIGHT};
        int kb;
        int dx = 0,dy = 0;
        switch(getch())
        {
                case 'w' :dy--;kb = UP;  break;
                case 's' :dy++;kb = DOWN;break;
                case 'a' :dx--;kb = LEFT;break;
                case 'd' :dx++;kb = RIGHT;break;
                default  :NULL;break; 
        }
        if(kb == UP&& *Cry+1<=2)
        {
                map[*Cry][*Crx] = map[*Cry+1][*Crx];
                map[*Cry+=1][*Crx] = ' ';
        }
        if(kb == DOWN&&*Cry-1>=0)
        {
                map[*Cry][*Crx] = map[*Cry-1][*Crx];
                map[*Cry-=1][*Crx] = ' ';
        }
        if(kb == LEFT&&        *Crx+1<=2)
        {
                map[*Cry][*Crx] = map[*Cry][*Crx+1];
                map[*Cry][*Crx+=1] = ' ';
        }
        if(kb ==RIGHT&& *Crx-1>=0)
        {
                map[*Cry][*Crx] = map[*Cry][*Crx-1];
                map[*Cry][*Crx-=1] = ' ';
        }
        
        return;
}
void RandMap(char map[][3])
{
        
        int i,j,k,n = 0;
        srand((unsigned)time(NULL));
        for(i = 0;i<8;i++)
        {
                map[0][i] = '1'+i;
        }
        while(n<99)//随机交换99次,这个算法不太好,容易出现死局 
        {
                int tem;
                j = rand()%8; 
                k = rand()%8;
                if (k-j == 1||j-k == 1||k-j == 3||j-k == 3)
                {
                        continue;//减小死局出现的概率,相邻位置的数字不能交换 
                }
                tem = map[0][k];
                map[0][k] = map[0][j];
                map[0][j] = tem;
                n++;
        }//这个算法可以实现指定数组的乱序排列,但对本游戏不太合适,乱序不保证游戏有解 
        
        
        map[2][2] = ' ';
 
}
int Help(void)
{
        int judje = 0;
        system("cls");
        printf("点击开始游戏,程序会随机生成一个数阵,例如\n"
                        "314\n286\n75 \n点击wasd移动数字,直至\n123\n456\n78 \n则胜出\n");
        printf("返回菜单吗?\t   =====   y/n\n");
        do{
                int ch = getchar();
                if(ch == 'y')
                {
                        return 1;
                }
                if(ch == 'n')
                {
                        judje = 1;
                }
        }while(judje == 1);
} 
int About(void)
{
        int judje = 0;
        system("cls"); 
        printf("本游戏由莫言情难忘改编\n编程之路,从这里开始\n");
        printf("返回菜单吗?\t   ======    y/n\n");
        do{
                int ch = getchar();
                if(ch == 'y')
                {
                        return 1;
                }
                if(ch == 'n')
                {
                        judje = 1;
                }
        }while(judje == 1);
}
int IsWin(char map[][3])
{
        int i;
        int j = 0;
        for(i = 0;i<8;i++)
        {
                if (map[0][i] == '1'+i)
                j++;
        }
 
   if (j == 8)
   {
                   return 1;
   }
   else 
   {
                   return 0;
   }
 
 
} 
void Game(void)
{
        char Map[3][3] = {0};
        int Crx = 2;
        int Cry = 2;
        RandMap(Map);//先生成一个
        Show(Map);
        printf("任意键开始游戏!!\n");
        getch();
        unsigned int t1 = time(NULL);
        while(1)
        {
                MoveNumber(Map,&Crx,&Cry);//用户操作 
                Show(Map);
                unsigned int t2 = time(NULL);
                if(IsWin(Map))
                {
                        printf("胜利~!用时%dS",t2-t1);
                        return;
                }
        }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

用C++来解决3*3拼图的问题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何解析OpenLayers 3加载矢量地图源的问题

今天就跟大家聊聊有关如何解析OpenLayers 3加载矢量地图源的问题,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、矢量地图矢量图使用直线和曲线来描述图形,这些图形的元素是一些
2023-06-22

利用Anaconda完美解决Python 2与python 3的共存问题

前言 现在Python3 被越来越多的开发者所接受,同时让人尴尬的是很多遗留的老系统依旧运行在 Python2 的环境中,因此有时你不得不同时在两个版本中进行开发,调试。 如何在系统中同时共存 Python2 和 Python3 是开发者不
2022-06-04

C++中常见的字符串拼接问题解决方案

C++中常见的字符串拼接问题解决方案在C++编程中,字符串拼接是一种常见的操作,特别是在处理文本和输出结果时。本文将介绍一些常见的字符串拼接问题,并提供相应的解决方案,同时附上代码示例以帮助读者理解。使用"+"运算符进行字符串拼接在C++中
2023-10-22

C++中常见的字符串拼接问题的解决方案

C++中常见的字符串拼接问题的解决方案在C++编程中,字符串拼接是一个常见的操作,通常用于拼接两个或多个字符串,或者将其他数据类型转换为字符串后进行拼接。在处理字符串拼接的过程中,我们需要考虑到性能和代码的简洁性。本文将介绍几种常见的字符串
2023-10-22

RedisCluster是用来解决什么问题的

RedisCluster是用来解决Redis单节点的性能瓶颈和可用性问题的。它通过将数据分片存储在多个节点上,并通过集群管理器对这些节点进行管理,从而实现了分布式存储和负载均衡。通过使用RedisCluster,可以提高Redis的可用性和
RedisCluster是用来解决什么问题的
2024-04-09

iOS使用WebView生成长截图的第3种解决方案

前言WebView就是一个内嵌浏览器控件,在iOS中主要有两种WebView:UIWebView和WKWebView,UIWebView是iOS2之后开始使用,WKWebView是在iOS8开始使用,WKWebView将逐步取代笨重的UIW
2022-05-23

C++中指针问题及引用问题的解决方法

C++中指针问题及引用问题的解决方法在C++编程中,指针是一种非常重要的数据类型,允许我们直接访问内存地址。然而,指针也经常会导致一些问题,例如空指针引用和悬空指针引用。此外,我们还经常会遇到引用问题,例如引用类型的函数参数传递和返回值引用
2023-10-22

C++中指针问题和引用问题的解决方法

C++中指针问题和引用问题的解决方法引言:在C++编程过程中,指针问题和引用问题是常见的困扰程序员的难题。本文将介绍一些解决这些问题的方法,并通过具体的代码示例进行说明,帮助读者更好地理解和应用。一、指针问题的解决方法空指针检测在使用指针之
2023-10-22

c#中使用Environment.Exit的问题怎么解决

在C#中,使用Environment.Exit方法可以立即终止应用程序的执行。如果您想解决使用Environment.Exit方法的问题,可以尝试以下几种方法:使用return语句:在需要终止程序的地方,可以使用return语句直接返回,这
c#中使用Environment.Exit的问题怎么解决
2024-02-29

C++ 函数的递归实现:如何使用递归来解决数学问题?

递归是一种函数调用自身的编程技巧,用于解决复杂问题。在数学问题中,递归应用广泛,例如:计算阶乘:fac++torial(n) = n * factorial(n-1) if n > 0,factorial(0) = 1计算斐波那契数列:fi
C++ 函数的递归实现:如何使用递归来解决数学问题?
2024-04-22

python使用matplotlib绘图时图例显示问题的解决

前言 matplotlib是基于Python语言的开源项目,旨在为Python提供一个数据绘图包。在使用Python matplotlib库绘制数据图时,需要使用图例标注数据类别,但是传参时,会出现图例解释文字只显示第一个字符,需要在传参时
2022-06-04

VUE懒加载技术剖析,只用3行代码解决百万级图片加载难题

VUE懒加载技术是一种先进的图片加载技术,它可以将图片的加载延迟到需要的时候才进行,从而提高页面的加载速度和性能。只需要3行代码,就可以轻松解决百万级图片的加载难题。
VUE懒加载技术剖析,只用3行代码解决百万级图片加载难题
2024-02-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录