一个笔试题目

题目

九宫格配合加减乘除,横竖都等于4

这里写图片描述

百度知道上有人类的解法。


这里讨论一下用代码来求解。假设每一个变量在0-100之间,在不使用求解公式,降维的前提下编程解题。

解法1:每个未知数是一个变量,8个未知数就是8个变量,每个变量可以的取值为0-100。需要8层循环,遍历所有的变量的值。再计算公式是否符合要求。

解法2:循环太多,看起来不爽,想了一个方法循环改为递归

循环遍历改为递归遍历,其实性能上还不如循环,只是看起来好看一点。

#include<stdio.h>

int num[8] = {0}; // 代表8个未知数,从左到右,从上到下

// 第depth层循环
void compute(int depth) {

    if (depth < 8)
        for (int i = 0; i <= 100; i++) {
            if (depth == 5 && i == 0) // num[5] 不能是0,除数
                continue;
            num[depth] = i;
            compute(depth + 1);
        }
    // 只有到了第8层循环,num中的8个数字才会全部赋值完成,此时计算
    else { 

        if (num[0] + num[1] - 9 != 4)
            return;

        if (num[2] - num[3] * num[4] != 4)
            return;

        if (num[5] + num[6] - num[7] != 4)
            return;

        if (num[0] + num[2] / num[5] != 4)
            return;

        if (num[1] - num[3] * num[6] != 4)
            return;

        if (9 - num[4] - num[7] != 4)
            return;
        // 所有的公式都符合,输出
        for (int j = 0; j < 8; j++)
            printf("%d ", num[j]);
        printf("\n");
    }
}

int main() {
    compute(0);
}

解法3:把一些公式的计算提前,比如第一个公式不需要计算出所有的值,只需要前两个值赋值,就可以做判断

#include<stdio.h>

int num[8] = {0};

void show() {
    for (int j = 0; j < 8; j++)
        printf("%3d ", num[j]);
    printf("\n");
}

void compute(int depth) {
    // show();

    if (depth == 2) // 此时num[0] num[1]的值已赋值
        if (num[0] + num[1] - 9 != 4)
            return;

    if (depth == 5)
        if (num[2] - num[3] * num[4] != 4)
            return;

    if (depth == 6)
        if (num[0] + num[2] / num[5] != 4)
            return;


    if (depth < 8)
        for (int i = 0; i <= 100; i++) {
            if (depth == 5 && i == 0)
                continue;
            num[depth] = i;
            compute(depth + 1);
        }
    else {

        if (num[5] + num[6] - num[7] != 4)
            return;

        if (num[1] - num[3] * num[6] != 4)
            return;

        if (9 - num[4] - num[7] != 4)
            return;
        show();

    }
}


int main() {
    compute(0);
}


简单优化之后,可以在短时间内出结果了。

这里写图片描述

但是在C语言中,整数2/8是等于0的,所以出现了一些不符合常理的答案,但是符合整数运算。

修改一下,把 int num[8], 改为 double num[8]; printf(“%3d “)改为printf(“%lf “);

这里写图片描述

只有一个答案了。

此时答案跟百度知道的答案还是不一样,那是因为百度知道的解法是忽略运算符的优先级,按照出现次序计算。按照这个思路修改代码如下。

#include<stdio.h>

double num[8] = {0};

void show() {
    for (int j = 0; j < 8; j++)
        printf("%lf ", num[j]);
    printf("\n");
}

void compute(int depth) {
    // show();

    if (depth == 2)
        if (num[0] + num[1] - 9 != 4)
            return;

    if (depth == 5)
        if ((num[2] - num[3]) * num[4] != 4)
            return;

    if (depth == 6)
        if ((num[0] + num[2]) / num[5] != 4)
            return;


    if (depth < 8)
        for (int i = 0; i <= 100; i++) {
            if (depth == 5 && i == 0)
                continue;
            num[depth] = i;
            compute(depth + 1);
        }
    else {

        if (num[5] + num[6] - num[7] != 4)
            return;

        if ((num[1] - num[3]) * num[6] != 4)
            return;

        if (9 - num[4] - num[7] != 4)
            return;
        show();

    }
}


int main() {
    compute(0);
}

百度知道上的答案出现了。

这里写图片描述

应该还可以用解方程的算法

( 女朋友刚刚笔试的题目 )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值