火柴棍移动的一道面试题

最近有朋友找工作,面试某公司,遇到一个火柴棍移动的面试题,感觉有点意思,在此抛砖引玉。

题目大致是这样的:

一个三个数的式子,移动其中一根火柴,使等式成立,用程序或实现(可以用伪码),输出能成立的等式。

注:“+”可以移走一根火柴变成“-”

例如:

废话不说,直接上代码,哪位网友有更好的方法,请分享一下,多谢

#include <stdio.h>

/* 定义操作符号,"+"或"-" */
#define SYMBOL_ERROR 0
#define SYMBOL_ADD   1
#define SYMBOL_MINUS 2

/* 定义变化标识,取值原则:3个中随便取出n个相加不能等于其中一个数 */
#define FLAG_NO    0     /* 没有移动 */
#define FLAG_MINUS 10    /* 去一根火柴 */
#define FLAG_ADD   100   /* 增加一根火柴 */
#define FLAG_SELF  1000  /* 拿一根放自己身上另外的位置 */

/* 定义合法移动 */
#define MOVE_TO_ANOTHER 110   /* 10 + 100 + 0,一个数拿一根,放到另一个数上 */
#define MOVE_TO_SELF    1000  /* 1000 + 0 + 0,自己拿一根放自己身上其他位置 */
#define MOVE_FROM_PLUS  100   /* 100 + 0 + 0,从加号上拿一根放一个数身上 */

/* 定义火柴移动结构体 */
typedef struct matchstick
{
    int iFlag; /* 变化标识 */
    int iData; /* 火柴表示的数 */
}MATCH_STICK_S;

/*
  获取一个数不动或移动一根火柴后得到的数(只列举3和6,其他数值类似)
  入参:指定的数(0-9)
  出差:MATCH_STICK_S结构数组
  返回值:移动一根火柴得到的数的个数
*/
int getDataAfterMoveStick(int iData, MATCH_STICK_S *pstStick)
{
    int iCount = 0;

    switch(iData)
    {
        case 3:
        {
            pstStick[0].iFlag = FLAG_NO; pstStick[0].iData = 3;   /* 不动 */
            pstStick[1].iFlag = FLAG_ADD; pstStick[1].iData = 9;  /* 加一根 */
            pstStick[2].iFlag = FLAG_SELF; pstStick[2].iData = 2; /* 自己移动一根 */
            pstStick[3].iFlag = FLAG_SELF; pstStick[3].iData = 3;
            pstStick[4].iFlag = FLAG_SELF; pstStick[4].iData = 5;
            iCount = 5;
            break;
        }
        case 6:
        {
            pstStick[0].iFlag = FLAG_NO; pstStick[0].iData = 6;    /* 不动 */
            pstStick[1].iFlag = FLAG_ADD; pstStick[1].iData = 8;   /* 加一根 */
            pstStick[5].iFlag = FLAG_MINUS; pstStick[5].iData = 5; /* 减一根 */
            pstStick[2].iFlag = FLAG_SELF; pstStick[2].iData = 0;  /* 自己移动一根 */
            pstStick[3].iFlag = FLAG_SELF; pstStick[3].iData = 6;
            pstStick[4].iFlag = FLAG_SELF; pstStick[4].iData = 9;
            iCount = 6;
            break;
        }
        default:
        {
            break;
        }
    }

    return iCount;
}

/* 移动火柴
   返回值:
   SYMBOL_ERROR:非法移动
   SYMBOL_MINUS:从"+"上取一根加到某个数上
   SYMBOL_ADD:  不从"+"取火柴时,移动一根
 */
char checkStickMove(int iFlag1, int iFlag2, int iFlag3)
{
    char cSymbol = SYMBOL_ERROR;
    int iFlagSum = iFlag1 + iFlag2 + iFlag3;

    if((MOVE_TO_ANOTHER == iFlagSum) || (MOVE_TO_SELF == iFlagSum))
    {
        cSymbol = SYMBOL_ADD;
    }
    else if(MOVE_FROM_PLUS == iFlagSum)
    {
        cSymbol = SYMBOL_MINUS;
    }

    return cSymbol;
}

/* 满足移动规则,并能使等式成立的,打印出来 */
void printResult(MATCH_STICK_S *pstStick1, MATCH_STICK_S *pstStick2, MATCH_STICK_S *pstStick3)
{
    int iFlag1 = pstStick1->iFlag;
    int iFlag2 = pstStick2->iFlag;
    int iFlag3 = pstStick3->iFlag;
    int iData1 = pstStick1->iData;
    int iData2 = pstStick2->iData;
    int iData3 = pstStick3->iData;

    char cSymbol = checkStickMove(iFlag1, iFlag2, iFlag3);

    if((SYMBOL_ADD == cSymbol) && (iData3 == iData1 + iData2))
    {
    	printf("%d + %d = %d\n", iData1, iData2, iData3);
    }
    else if((SYMBOL_MINUS == cSymbol) && (iData3 == iData1 - iData2))
    {
    	printf("%d - %d = %d\n", iData1, iData2, iData3);
    }

    return;
}

/* 处理火柴移动 */
void dealStickMove(int iData1, int iData2, int iData3)
{
    unsigned long ulLoop1, ulLoop2, ulLoop3;
    int iCount1, iCount2, iCount3;
    MATCH_STICK_S astStick1[10];
    MATCH_STICK_S astStick2[10];
    MATCH_STICK_S astStick3[10];

    iCount1 = getDataAfterMoveStick(iData1, astStick1);
    iCount2 = getDataAfterMoveStick(iData2, astStick2);
    iCount3 = getDataAfterMoveStick(iData3, astStick3);

    for(ulLoop1 = 0; ulLoop1 < iCount1; ulLoop1++)
    {
        for(ulLoop2 = 0; ulLoop2 < iCount2; ulLoop2++)
        {
            for(ulLoop3 = 0; ulLoop3 < iCount3; ulLoop3++)
            {
                printResult(&astStick1[ulLoop1], &astStick2[ulLoop2], &astStick3[ulLoop3]);
            }
        }
    }

    return;
}

int main()
{
    dealStickMove(3, 6, 3);

    return 0;
}

运行结果:

3 + 0 = 3

9 - 6 = 3

火柴棍移动的一道面试题

时间: 2024-10-14 05:20:50

火柴棍移动的一道面试题的相关文章

CDOJ 1260 火柴棍数字(二)

Fish是一条生活在海里的鱼,有一天他很无聊,于是他去捡了人类扔进海里的垃圾,打算用这些来玩些什么. 他从捡回来的垃圾堆里找到了n根火柴棍,他想把这些火柴棍拼成一个长度为m的十进制数,每个数字的拼法如下图所示. 他想拼出来的数尽量大,这该怎么拼呢? 聪明的你,肯定知道该如何利用这n根木棒得到最大的m位数. 那就快告诉Fish吧~ 当然,不能有前导0哦. 而且木棍得全部用完! Input 第一行输入两个整数,n,m 满足 1<=n,m<=105 Output 将这m位数输出 如果不能得到任何一个

一道面试题: C能申请的最大全局数组大小?

一道面试题: C能申请的最大全局数组大小?第一反应好像是4GB,但明显不对,代码和数据都要占空间,肯定到不了4GB.但是又想内存可以和硬盘数据交换,那到底是多少?应该是32位系统是理论上不能超过4GB(因为地址宽度4bytes,寻址的限制),实际中由于OS实现的细节会更少(比如Linux 1GB给了内核),而64位系统不超过2^64-1:内存大小最好大于数组长度,否则导致和磁盘交换数据,性能下降如果是局部变量,分配在栈上,空间会更小,取决于编译器 参考:http://stackoverflow.

[Swust OJ 179]--火柴棍(找规律)

题目链接:http://acm.swust.edu.cn/problem/0179/ Time limit(ms): 1000 Memory limit(kb): 65535 Description 火柴棍可以拼成10进制的数字,如图所示: 现在,gogo给你个n个火柴棍,要求你输出最小能拼成的数字和最大能拼成的数字. Input 第一行输入一个整数T:T组测试数据(T<100) 每行输入一个n (2 ≤ n ≤ 100): 表示你有的火柴棍数. Output 最小能拼成的数字和最大能拼成的数字

华为的一道机试题--等式变换

华为的一道机试题 (http://blog.csdn.net/zombie_slicer/article/details/37346025) 第三题:等式变换 输入一个正整数X,在下面的等式左边的数字之间添加+号或者-号,使得等式成立. 1 2 3 4 5 6 7 8 9 = X 比如: 12-34+5-67+89 = 5 1+23+4-5+6-7-8-9 = 5 请编写程序,统计满足输入整数的所有整数个数. 输入:       正整数,等式右边的数字 输出:       使该等式成立的个数 样

Java中有关构造函数的一道笔试题解析

Java中有关构造函数的一道笔试题解析 1.具体题目如下 下列说法正确的有() A. class中的constructor不可省略 B. constructor必须与class同名,但方法不能与class同名 C. constructor在一个对象被new时执行 D.一个class只能定义一个constructor 2.解析说明 (1)class中的构造函数是可以省略的 /** * @Title:User.java * @Package:com.you.user.model * @Descrip

Android多线程研究(4)——从一道面试题说起

有一道这种面试题:开启一个子线程和主线程同一时候运行,子线程输出10次后接着主线程输出100次,如此重复50次.先看以下代码: package com.maso.test; /** * * @author Administrator * 两个线程,当中是一个主线程,第一个线程先运行输出10次,主线程接着运行输出100次,如此重复50次 */ public class ThreadTest3 implements Runnable{ private static Test test; @Overr

0810------笔试题----------腾讯2012年的一道笔试题

1.题目要求 a)b[i] = a[0] *a[1] *a[2]*….a[n-1]/ a[i],求出数组b: b)要求不能用除法,除循环控制变量以外,不许额外申请其余变量,时间复杂度为O(n),空间复杂度为O(1). 2.程序思路 a)假设 N = 5,那么 b[0] =      a[1]*a[2]*a[3]*a[4];            b[1] = a[0]*     a[2]*a[3]*a[4];            b[2] = a[0]*a[1]*     a[3]*a[4];

关于阿里的一道笔试题分析

其题目如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #pragma pack(2) class A { public:     int i;     union U     {         char buff[13];         int i;     }u;     void foo() {    }     typedef char* (*f)(void*);     enum{red, green, blue} color; }a; class A

关于Java类加载双亲委派机制的思考(附一道面试题)

预定义类加载器和双亲委派机制 JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar).由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作. 标准扩展(Extension)类加载器:是由 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)