哔哩哔哩2018.9.21笔试题——扭蛋机(堆的思想解决)

一、题目:扭蛋机
甲乙俩人刚开始都没有蛋,甲扭2号机,乙扭3号机。
(1)扭蛋机的规则:
2号扭蛋机:2x+1
3号扭蛋机:2
x+2
eg: 如果甲刚开始没有蛋,扭一下2号机,获得2*0+1=1颗蛋。
(2)游戏规则:
要求以最少的次数恰好扭出N个蛋。
(3)扭蛋规则:
甲乙俩人部分先后,一人扭完蛋将所有的蛋交由另一个人扭或者自己扭,但是要保证扭蛋次数最少,且恰好扭出N个蛋。

(4)输入输出:
输入:需要扭出的N个蛋。
输出:依次使用扭蛋机的编号。
(5)eg:
输入:
10
输出:
233

二、思路:
1、将扭蛋的题目转化为在堆中查找某一节点:从堆顶到该节点的路径。
看到扭蛋机的规则中的2x+1、2x+2。
想到用堆:
2x+1 为左孩子(-------------向左走:扭2号机后,当前拥有的总蛋数),
2
x+2 为右孩子(-------------向右走:扭3号机后,当前拥有的总蛋数),
x 为父亲 (-------------没走前:没扭扭蛋机之前拥有的总蛋数)。
且无需建堆操作:
因为 0~N,既是下标,也是数组中的存储元素(-------------当前拥有的扭蛋数)。
所以,遍历数组时,直接取对应下标即可,无需弄一个数组专门存放堆中元素。
哔哩哔哩2018.9.21笔试题——扭蛋机(堆的思想解决)_第1张图片
eg:要扭到10个蛋,必须走0->1->4->10这一条路,且堆的高度最小。

2、在堆中查找某一节点:从堆顶到该节点的路径。
从该节点开始,一路向上查找父节点,直至遇到堆顶元素为止,将遇到的父节点按时间先后顺序依次存储在栈中,最后,将栈中元素逆序输出即可。

	int k;
	cin>>k;//恰好扭出k个蛋
	stack s;
	s.push(k);
	while (((k - 1) / 2) > 0){
		k = (k - 1) / 2;
		s.push(k);
	}

	while (!s.empty()){
		int x = s.top();
		s.pop();
		cout << x << " ";
	}

最后,对栈中输出的元素进行数值判断,如果是左孩子,输出2,如果是右孩子输出3。
这样就满足题目要求啦!!

三、代码如下:

#include
#include
using namespace std;
//扭蛋机
int main(){
	int k;
	cin >> k;//恰好扭出k个蛋
	stack s;
	s.push(k);
	while (((k - 1) / 2) > 0){
		k = (k - 1) / 2;
		s.push(k);
	}

	while (!s.empty()){
		int x = s.top();
		s.pop();
	//	cout << x << " ";
		if (x % 2)cout << 2;
		else cout << 3;
	}
	cout << endl;
}

测试了10组数据:
哔哩哔哩2018.9.21笔试题——扭蛋机(堆的思想解决)_第2张图片

你可能感兴趣的:(数据结构,笔试题)