移动火柴问题的程序解法及生成算法

闲的蛋疼:用算法解移动一根火柴问题 最近一直看到诸如的问题,闲的无聊,便写了段代码来自动解答这类问题。初步只能支持标准的数字变化,即9可以变成3,5,6等,但是不能变成13因为一根火柴棍形成不了1(1需要两根火柴棍).另外数字间不能插入符号,例如132不能变成13-2,因为没有空间可以插入。允许更为灵活的变换需要更多的代码,在此不过多深入思考了思路如下:1)首先求出每个字符“0~9 - +”增加一根火柴,减少一根火柴,自身移动一根火... 阅读详情

在电视上看到的游戏,规则是:
移动1根(目前只看到1根的,或许有两根或以上,不过再多就比较难了)火柴,使给出的4位数成为最大(或最小)。
当然火柴不能弄断,也不能消失什么的,这点和偶们小学暑假作业的那种不一样。
因此这种题用偶擅长的穷举法来解是最合适不过的了。
生成的算法……随机产生!不过产生后可以根据输出的match参数判断题目大概的难度,match的越多应该就越难。
程序会用字符拼出火柴的摆放形状以便观察。
程序的使用方式是(假设编译为match.exe):
  match 
  生成随机数并给出答案
  match 数字
  解得给出的数
程序在linux gcc上编译通过。



#include 
<stdio.h>
#include 
<stdlib.h>
// count of digits
#define DIGITS          4
// how many time(s) of movement allowed
#define MAXMOVE         1

#define WIDTH           (DIGITS * 4)
#define HEIGHT          5

const unsigned char LED[10] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x27, 0x7F, 0x6F };
const unsigned char MASKS[7][3] = {
        
{ 0x00, 0x10, 0x20 },
        
{ 0x20, 0x21, 0x22 },
        
{ 0x22, 0x23, 0x24 },
        
{ 0x04, 0x14, 0x24 },
        
{ 0x02, 0x03, 0x04 },
        
{ 0x00, 0x01, 0x02 },
        
{ 0x02, 0x12, 0x22 }
}
;

void print_num(int num)
{
        
char buf[WIDTH][HEIGHT];
        
int i, j, k, mask, left;
        memset(buf, 
0, sizeof buf);
        left 
= WIDTH - 4;
        
for ( i = 0; i < DIGITS; ++i, left -= 4 ) {
                mask 
= LED[num % 10];
                num 
/= 10;
                
for ( j = 0; j < 7; ++j, mask >>= 1 ) {
                        
if ( mask & 1) {
                                
for ( k = 0; k < 3; ++k ) buf[(MASKS[j][k] >> 4) + left][MASKS[j][k] & 0xF] = 1;
                        }

                }

        }

        
for ( j = 0; j < HEIGHT; ++j ) {
                
for ( i = 0; i < WIDTH; ++i ) {
                        
if (buf[i][j]) printf("O"); else printf(" ");
                }

                printf(
" ");
        }

}


int is_valid(int led)
{
        
int i;
        
for ( i = 0; i < 10; ++i ) if (led == LED[i]) return 1;
        
return 0;
}


int led_to_num(unsigned char *leds)
{
        
int num = 0, i, j, mod = 1;
        
for ( i = 0; i < DIGITS; ++i ) {
                
for ( j = 0; j < 10; ++j ) {
                        
if (leds[i] == LED[j]) {
                                num 
= num + j * mod;
                                
break;
                        }

                }

                mod 
*= 10;
        }

        
return num;
}


// do a move, change two digits' led, returns non-zero if it results valid numbers
int move(unsigned char* srcled, unsigned char* destled, int srcindex, int destindex)
{
        
if ( ((*srcled) & (1 << srcindex))
                        
&& !((*destled) & (1 << destindex)) ) {
                
// off the src pos
                *srcled &= ~(1 << srcindex);
                
// light the dest pos
                *destled |= (1 << destindex);
                
return is_valid(*srcled) && is_valid(*destled);
        }

        
return 1; // not moved
}


void try_level(int level, unsigned char *leds, int *maxnum, int *minnum, int *match)
{
        unsigned 
char tmpleds[DIGITS];
        
int srcled, destled, srcindex, destindex;
        
int n;
        
for ( srcled = 0; srcled < DIGITS; ++srcled ) {
                
for ( destled = 0; destled < DIGITS; ++destled ) {
                        
for ( srcindex = 0; srcindex < 7; ++srcindex ) {
                                
for ( destindex = 0; destindex < 7; ++destindex ) {
                                        
if (srcled == destled && srcindex == destindex) continue; // the same
                                        memcpy(tmpleds, leds, sizeof tmpleds);
                                        
if ( move(&tmpleds[srcled], &tmpleds[destled], srcindex, destindex) ) {
                                                
if (level == 0) {
                                                        n 
= led_to_num(tmpleds);
                                                        
if ( n > *maxnum ) *maxnum = n;
                                                        
if ( n < *minnum ) *minnum = n;
                                                        
++(*match);
                                                }

                                        }

                                        
if (level > 0) try_level(level - 1, tmpleds, maxnum, minnum, match);
                                }

                        }

                }

        }

}


int main(int argc, char* argv[])
{
        unsigned 
char leds[DIGITS];
        unsigned 
char tmpleds[DIGITS];
        
int maxnum = -1, minnum = 0x7FFFFFFF;
        
int match = 0;
        
int i;
        
int num, numtemp, m, mod;

        srand(time(NULL));

    
if (argc == 2) sscanf(argv[1], "%d", &numtemp);
    
else numtemp = rand();

        
// generate leds
        num = 0;
        
for (i = 0, m = numtemp, mod = 1; i < DIGITS; ++i) {
                leds[i] 
= LED[m % 10];
                num 
+= (m % 10) * mod;
                m 
/= 10;
                mod 
*= 10;
        }


        try_level(MAXMOVE 
- 1, leds, &maxnum, &minnum, &match);

        printf(
"number=%d movements=%d matches=%d maxnum=%d,minnum=%d ",
                num, MAXMOVE, match, maxnum, minnum);
        printf(
"NUMBER: ");
        print_num(num);
        printf(
"MAX: ");
        print_num(maxnum);
        printf(
"MIN: ");
        print_num(minnum);

        
return 0;
}

 
闲的蛋疼:用算法解移动一根火柴问题(二) 本文仅个人娱乐所用。趁着空闲,把昨天的程序完善了下,做成了一个控制台小游戏。不得不说,我的智商被爆了。import random class ActionType: Dec = 0 #将火柴移出 Inc = 1 #将火柴移入 SelfTrans = 2 class PositionType: Default = 0 FrontEmpty = 1 cl... 阅读详情

相关推荐

CSP考试复习:第二单元 基础算法 2.2 火柴棒等式 2.3 梵塔问题 2.4 斐波那契数列

题目来源:NOIP2008 第二题 2.2 火柴棒等式 【问题简述】给你 n(n≤24)根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的 A、B、C 是 用火柴棍拼出的整数(若该数非零,则最高位不能是 0),数字的形状和电子表上的一样。 注意: 1. 加号与等号各自需要两根火柴棍。 2. 如果 A≠B,则 A+B=C 与 B+A=C 视为不同的等式(A,B,C≥0)。 3. n 根火柴棍必须全部用上。 【分析】 直接枚举 A 和 B(事实证明只到 3 位数)。为了加快速度,事先把 222 .

zhengheda的博客 346

b - 火柴棒等式_移动火柴问题-完整解答|小学提高篇1

弘毅问我一个小学三四年级的问题。请移动一根火柴棒,使得等式成立:刚开始我也是一脸蒙圈,但是十几分钟后我找到一个答案:9-3=6.对于一个数学博士花了十几分钟才找到答案,我的内心是拒绝的!我还是我吗?我是谁?我在哪?冷静下来后,我在网上查了一下,出现的全是:史上最难小学奥赛题;小学数学题,以下10道全答对智商至少140......搞笑的是,几乎所有媒体都用了如下语句:“学历越高越做不出来!”这让我一...

weixin_26901145的博客 3121

翻转游戏算法解析:从组合博弈到尼姆值计算

组合博弈是研究离散决策过程的数学理论,其核心是通过博弈树分析游戏状态转移关系。在算法领域,这类问题常采用递归+记忆化技术优化,典型如尼姆游戏利用异或规则判断必胜策略。翻转游戏作为组合博弈的经典案例,将字符串操作转化为尼姆堆计算,展现了状态压缩与数学建模的巧妙结合。该模式在网络协议状态机、资源调度等工程场景中有广泛应用,本文通过热词'尼姆值'和'记忆化搜索',深入讲解如何将博弈论思想转化为高效算法实现。

weixin_29597551的博客 177

移动火柴(数学知识)

问题描述:在正方形的顶点处放上火柴。开始时在第一个顶点处放1根火柴,其他顶点处空着。移动火柴规则如下:可以在有火柴的任何顶点处移走任意根数的火柴,并在与之相邻的两个顶点处都放上移走火柴数的两倍。你的任务是判断是否经过若干次操作,4个顶点(顺或逆)处的火柴根数为事先指定的4个非负整数a,b,c,d(第一个数a对应第一个顶点火柴数)。 输入样例:                输出样例: 2 1

H煊的博客 2861

移动火柴棍

用C语言写的算法,四位数火柴棍移动其中一根变四位最大数。

火柴棒游戏VB源代码

内容索引:VB源码,游戏编程,VB游戏源代码  火柴棒游戏——MatchTricks的VB源代码,是一款益智类的传统小游戏,玩法也不难,根据屏幕提示移动火柴棒排成一定形状,右键可以旋转火柴,不过小时候没玩过这种游戏,你首先需要知道怎么玩才能写出游戏哦,所以有空休闲一下,玩一把娱乐一下。   

用Java解决移动火柴的问题

游戏的规则很简单:恰好移动一根火柴,使等式成立。如下面的等式可以变成3+6=9(还有其他解):移动哪一根火柴能使等式成立?请你写一个程序,找出所有的规范解。所谓规范是指:     * 只能改变数字,不能改变符号;     * 数字和符号的组成方式必须严格的和图示的一样(减号由一根火柴组成);     * 新等式必须形如a+b=c或a-b=c,其中a、b、c都是不含前导0的非负整数。 当然,最重要的是:新的等式必须在数学上成立。实现代码:import java.io.BufferedReade

降龍 2969

移动一根火柴使等式成立js版本

移动一根火柴使等式成立js版本

关于火柴棒数字游戏的方案设计思考

这是学习笔记的第2468篇文章 同样,这是一个耽搁了数月之久的事情,关于火柴棒数字游戏,在奥数题中经常能刷到,还是蛮考验思维的。孩子很喜欢这种题目,我也觉得有意思,所以就花了一些时间琢磨了下。比如 拿走一根火柴棒,使得下面的等式成立或者是我在去年发的一道题目,一道移动火柴的题目,要不要试一下这种题目难就难在,可以同时有多种解法带着好奇心,我做了下分析,怎么能够写程序生成这样的题目,我没有着急...

杨建荣的学习笔记 1995

移动火柴游戏

基于c++Bulider做的一款小游戏,移动火柴棍游戏,含整个工程文件

几何修复_ANSYS流体分析:几何前处理

建模及几何处理工具非常多,选择起来让人眼花缭乱。对于仿真而言,高效的对几何进行清理及生成符合仿真要求的几何至关重要。ANSYS SpaceClaim Direct Modeler是基于直接建模思想的新一代3D高效率建模和几何编辑修补软件。SCDM提供了当今最快速、最富有创意的直接建模解决方案。由于它的直接建模能力即使对于导入的其它3D模型(如catia、proe、solid works创建的几何)...

weixin_35778830的博客 2416

火柴排队(codevs 3286)题解

【问题描述】 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:,其中 ai表示第一列火柴中第 i 个火柴的高度,bi表示第二列火柴中第 i 个火柴的高度。每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出

PbTfcLx 1091

Pytorch transformers tokenizer 分词器词汇表添加新的词语和embedding

NLP添加新词汇

7322

“火柴棍式”程序员面试题

有时候,有些面试题是很是无厘头,这不,又有一个,还记得小时候玩的的“火柴棍游戏”吗,就是移动一根火柴棍改变一个图或字的游戏.程序面试居然也可以这么玩,看看下面这个火柴棍式的程序面试题吧. 下面是一个C程序,其想要输出20个减号,不过,粗心的程序员把代码写错了,你需要把下面的代码修改正确,不过,你只能增加或是修改其中的一个字符,请你给出三种答案。 int n = 20; for(

尘世中迷途小书童 1439

利用kettle进行数据库数据比对

Kettle是一款国外开源的ETL工具,纯java编写,可以在Windows、Linux、Unix上运行,数据抽取高效稳定。本人用的版本是6.1。 之前用kettle这个开源的ETL工具是用来做数据抽取的,这次测试有个需求,是做数据库数据的比对。验证源表到目标表的逻辑正确,从而利用源表自己写SQL逻辑,生成的结果和目标表去比对。这次想到了利用kettle的数据比较功能,来做这些数据校验。 ...

多米诺DU的专栏 1万+

DSP配置I2C通讯(非IO口软件模拟时序)

dsp即数字信号处理器,是一种广泛应用的嵌入式处理器,主要应用是实时快速地实现各种数字信号处理算法,目前,国际主要的dsp供应商是ti公司,其tms32系列产品占据了dsp市场近一半的份额,本文以TMS320F28377D为例,使用ti公司dsp开发工具ccs10.1配置i2c模块。 写这篇文章的缘由,因为市面上很多DSP其实内部是具有硬件I2C接口的,但由于网络上大部分资料和例程都是利用IO口模拟I2C时序进而实现I2C通讯的。给很多想学习硬件I2C通讯的小伙伴带来了困难。 下面先介绍一下配置步骤 1.E

weixin_44387442的博客 5544

运煤和火柴棒

1.     这个可能是一个比较经典的智力题了,和以前的那个《赛马问题》很相似,其题目如下: 你是山西的一个煤老板,你在矿区开采了有3000吨煤需要运送到市场上去卖,从你的矿区到市场有1000公里,你手里有一列烧煤的火车,这个火车最多只能装1000吨煤,且其能耗比较大——每一公里需要耗一吨煤。请问,作为一个懂编程的煤老板的你,你会怎么运送才能运最多的煤到集市? 这道题一开始

s651665496的专栏 434

【docker】第10篇 Failed with result ‘exit-code和Start request repeated too quickly和Failed to start Docker

【docker】解决 Failed with result 'exit-code'和Start request repeated too quickly和Failed to start Docker。

Fanjufei的博客 6818

2019阿里秋招一道笔试题(关于火柴拼出最大数字) - Android开发岗

欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和图片上传 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富的快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I ...

weixin_42907725的博客 4550

使用CloudCompare和CANUPO进行点云分类的编程指南

在本文中,我们将介绍如何使用CloudCompare和CANUPO库进行点云分类的编程。CloudCompare是一款功能强大的开源点云处理软件,而CANUPO是一个用于点云分类和分割的C++库。这只是一个简单的点云分类示例,CANUPO库还提供了其他更高级的功能和算法,以满足各种点云分类需求。该函数接受点云数据、地面点掩码和非地面点掩码作为输入,并将分类结果存储在这两个掩码向量中。完成安装后,我们可以开始编写点云分类的代码。最后,我们遍历点云数据,并根据地面点和非地面点的掩码将结果打印出来。

ByteWhisper的博客 1058

SAP RAP 里的 EML 全解:从语言定位到事务语义,再到真实案例的落地方式

摘要:EML(Entity Manipulation Language)是ABAP RAP模型的核心组件,作为ABAP的子集用于操作业务对象(BO)。它通过声明式语法(READ/MODIFY/EXECUTE/COMMIT)统一访问BO的行为与数据,并由RAP运行时自动处理校验、锁定、草稿管理等生命周期。EML将业务语义融入代码,确保与Fiori应用共享同一套校验逻辑,并通过FAILED/REPORTED/MAPPED管道传递错误与消息。其事务控制(IN LOCAL MODE与COMMIT ENTITIES)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 528

程序员面试题-火柴棍式-火车运煤

程序员面试题- 1. “火柴棍式” http://coolshell.cn/articles/3961.html 2011年3月21日陈皓 有时候,有些面试题是很是无厘头,这不,又有一个,还记得小时候玩的的“火柴棍游戏”吗,就是移动一根火柴棍改变一个图或字的游戏。程序面试居然也可以这么玩,看看下面这个火柴棍式的程序面试题吧。 下面是一个C程序,其想要输出20个减号,不过...

weixin_34413065的博客 107

Python李峋同款跳动的爱心(完整代码)

Python语言实现李峋同款可写字版跳动的爱心的完整代码。

AIGC 4万+

C/C++语言, 趣味问题

这个可能是一个比较经典的智力题了,和以前的那个《赛马问题》很相似,其题目如下: 你是山西的一个煤老板,你在矿区开采了有3000吨煤需要运送到市场上去卖,从你的矿区到市场有1000公里,你手里有一列烧煤的火车,这个火车最多只能装1000吨煤,且其能耗比较大——每一公里需要耗一吨煤。请问,作为一个懂编程的煤老板的你,你会怎么运送才能运最多的煤到集市? 这道题一开始看上去好像是无解的,因为你

SelfImprovement 1311

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

上一篇: [非技术]HCAL---程序员职业病之一
下一篇: 街头见闻
superarhow
博客等级 码龄23年 46粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值