帽子游戏猜数字算法JS实现

【题目描述】

在这里插入图片描述

【效果展示】

在这里插入图片描述

【算法思路】

  1. 从比例出发,只有符合特定比例的情况才能被猜出来。
  2. 能猜出来的情况:当自己取另外两数的和或差时,前面的人应该会猜出来,但是前面的人没有猜出来。说明只能是取和或差的另一种情况。所以,要从前两个人能猜出来的比例出发,另外两个人的数字比例不变,之前自己作为加数时,此时自己取另两数之和。反之取两数之差的绝对值。

【数据结构】

在这里插入图片描述
1. ans[n-1]代表第n次能猜出来时,数字的比例数组(包含多个比例)
2. 如n=1时,[[2,1,1]],代表第1次就能猜出来,A:B:C=2:1:1。
3. n=2时,[1,2,1]不用说明,那么问题来了,[2,3,1]是怎么来的?,观察n=1时的情况[2,1,1],因为n=2时是B猜出来的,所以,A和C的比例不变,而B为1,说明B取的是A-C。站在B的角度思考,如果B看到A:C=2:1,那么自己可以取1吗?不行,因为自己取1时,A看到的是B:C=1;1,他应该会猜出来,但是他没有。说明我不可能是1,所以我只能取3,即A:B:C=A:B:C=2:3:1。
4. 以此类推,n=3时,观察ans[0]和ans[1]。[1,1,2]不用说明,[2,1,3]是根据n=0时的[2,1,1]推出来的,在此不加赘述。
[1,2,3]是由n=1时的[1,2,1]推出来的,[2,3,5]由[2,3,1]。
5. n=4时,答案存在ans[3],观察ans[1]和ans[2]。…
6…

【总结】

当前的人能猜出来的情况要利用前面两个人能猜出来的情况进行推理,自己为加数时现在取和,自己为和时现在应作为加数。如果还不是很懂的话,可以看看js代码中的注释。

【源代码】

hatGame.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>帽子游戏</title>

    <!-- 引入样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <!-- 引入组件库 -->
    <script src="https://unpkg.com/vue@2/dist/vue.js"></script>
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>

<body>
    <center>
        <h1>帽 子 游 戏</h1>
        <div id="app">
            <div style="width: 20%;">
                <el-input v-model="n" placeholder="请输入n"></el-input>
                <el-input v-model="k" placeholder="请输入k" style="margin-top: 10px; "></el-input>
                <el-button @click='conf' style="margin-top: 20px; " type="success">  确认</el-button>
            </div>
            <p>{{text}}</p>
            <el-container style="height: 500px; margin-top: 20px; border: 1px solid #eee">
                <el-container>
                    <el-main>
                        <el-table :data="tableData">
                            <el-table-column 
                            type="index"
                            width="50">
                          </el-table-column>
                            <el-table-column prop="numA" label="A" width="140">
                            </el-table-column>
                            <el-table-column prop="numB" label="B" width="140">
                            </el-table-column>
                            <el-table-column prop="numC" label="C" width="140">
                            </el-table-column>
                        </el-table>
                    </el-main>
                </el-container>
            </el-container>
        </div>
    </center>
   <script src="js/main.js"></script>

</body>

</html>

main.js

var app = new Vue({
    el: '#app',
    data: {
        ans: [
            [
                [2, 1, 1]
            ],
            [
                [1, 2, 1],
                [2, 3, 1]
            ],
            [
                [1, 1, 2],
                [1, 2, 3],
                [2, 1, 3],
                [2, 3, 5]
            ]
        ],
        text: "",
        n: null,
        k: null,
        tableData: []
    },

    methods: {
        conf() {
            let n = this.n  
            let k = this.k
            let ans = this.ans          //ans存比例,tableData存显示数据
            this.tableData = []
            if (ans[n - 1] == null) {   //ans[n-1]代表第n次的比列数组,若尚未算出,调用函数算出比例
                this.figureTo(n - 1)
            }
            for (let i = 0; i < ans[n - 1].length; i++) {
                var base = 0
                var flag = false; //标记是否能除尽,能否生成答案
                switch (n % 3) {  //不同的人猜出来的分类
                    case 1:
                        if (k % ans[n - 1][i][0] != 0) {
                            break;
                        }
                        base = k / ans[n - 1][i][0]
                        flag = true
                        break;
                    case 2:
                        if (k % ans[n - 1][i][1] != 0) {
                            break;
                        }
                        base = k / ans[n - 1][i][1]
                        flag = true
                        break;
                    case 0:
                        if (k % ans[n - 1][i][2] != 0) {
                            break;
                        }
                        base = k / ans[n - 1][i][2]
                        flag = true
                        break;
                }
                if (flag) { //存入数据进行显示
                    this.tableData.push({  
                        numA: base * ans[n - 1][i][0],
                        numB: base * ans[n - 1][i][1],
                        numC: base * ans[n - 1][i][2],
                    })
                }

            }

            if (this.tableData.length != 0) this.text = "第" + this.n + "次猜出,猜出的值为" + this.k + "的情况:"
            else this.text = "输入不合理(产生小数)"
        },
        figureTo(n) { //算到ans[n]

            if (this.ans[n - 1] == null) { //前一个比列未算出
                this.figureTo(n - 1)
            }
            this.ans[n] = []
            let index = n % 3 //当前数在数组中的下标,例如 输入n=4,传到figureTo时n=3,是第1个人算出来的,下标为0
            let index_other1 = (index + 1) % 3, //另两个数的下标
                index_other2 = (index + 2) % 3

            for (let i = 0; i < this.ans[n - 2].length; i++) {  //利用前面第二个人的推断开始推
                let old = this.ans[n - 2][i][index],
                    other1 = this.ans[n - 2][i][index_other1],
                    other2 = this.ans[n - 2][i][index_other2],
                    tempans = []

                tempans[index_other1] = other1
                tempans[index_other2] = other2
                if (old == Math.abs(other1 - other2))
                    tempans[index] = other1 + other2
                else
                    tempans[index] = Math.abs(other1 - other2)

                this.ans[n].push(tempans)
            }
            for (let i = 0; i < this.ans[n - 1].length; i++) { //利用前面第一个人的推断开始推
                let old = this.ans[n - 1][i][index],
                    other1 = this.ans[n - 1][i][index_other1],
                    other2 = this.ans[n - 1][i][index_other2],
                    tempans = []
                tempans[index_other1] = other1
                tempans[index_other2] = other2
                if (old == Math.abs(other1 - other2))
                    tempans[index] = other1 + other2
                else
                    tempans[index] = Math.abs(other1 - other2)

                this.ans[n].push(tempans)

            }

        },
    },

})
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值