【题目描述】
【效果展示】
【算法思路】
- 从比例出发,只有符合特定比例的情况才能被猜出来。
- 能猜出来的情况:当自己取另外两数的和或差时,前面的人应该会猜出来,但是前面的人没有猜出来。说明只能是取和或差的另一种情况。所以,要从前两个人能猜出来的比例出发,另外两个人的数字比例不变,之前自己作为加数时,此时自己取另两数之和。反之取两数之差的绝对值。
【数据结构】
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)
}
},
},
})