嗶哩嗶哩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,既是下標,也是數組中的存儲元素(-------------當前擁有的扭蛋數)。
所以,遍歷數組時,直接取對應下標即可,無需弄一個數組專門存放堆中元素。
在這裏插入圖片描述
eg:要扭到10個蛋,必須走0->1->4->10這一條路,且堆的高度最小。

2、在堆中查找某一節點:從堆頂到該節點的路徑。
從該節點開始,一路向上查找父節點,直至遇到堆頂元素爲止,將遇到的父節點按時間先後順序依次存儲在棧中,最後,將棧中元素逆序輸出即可。

	int k;
	cin>>k;//恰好扭出k個蛋
	stack<int> 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<iostream>
#include<stack>
using namespace std;
//扭蛋機
int main(){
	int k;
	cin >> k;//恰好扭出k個蛋
	stack<int> 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組數據:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章