因为没有提前上测试平台,没看清楚机试要求,不知道可不可以切屏到IDE上编程,所以整晚所有编程题都是在京东的oj上做的,本来很简单的题,知道可以用那些思路但是因为不熟模板或者库函数的使用变得举步维艰,结束后自己码一下发现是很简单的。
当时只拍了一道题,为了避开色相头,拍的角度也不好,将就看吧。分析题意就知道,第一行数字为候选人的个数n,第二行数字为n个候选人目前的票数,其中小东的票数为该行的第一个数字。
做法就是,每次将小东的票数跟剩下的n-1个候选人的得票最高的那个比较,如果小东的票数低了,则从最高者拿走一票,以此类推,知道小东比剩下的n-1个候选人的最高得票还高,此时小东就当选了,输出累计的小东拿走的票数。如何每次得到剩下候选人的最高票数?一个做法就是排序,每次最高票候选人被拿走一票之后,重新排序n-1个候选人们的票数,得到最高票数。但是这种做法效率比较低下,如何获得最高得票和希望得到下一个最高得票,也就是只需要整个结构局部有序即可,可以考虑用一种常见的数据结构,就是堆,每次最高票候选人被抽走一票之后重新插入堆中,堆的删除和插入都是log(N)比排序高多了。而在C++中优先队列priority_queue就是一种堆的实现,事实上还有一些排序和队列的结合实现。默认的,priority_queue是最大堆。
#include <iostream>
#include <queue>
using namespace std;
int main() {
int n;
while (cin >> n) {
priority_queue<int> q;
int m, cordinate, votes = 0;
cin >> cordinate; // cordinate表示小东
n--;
// 剩下的n-1个人为其他候选人
while (n--) {
cin >> m;
q.push(m);
}
// 若小东不是最高票的,则找出当前最多票的候选人,从他拿走一票给到小东
while (cordinate <= q.top()) {
m = q.top();
q.pop();
q.push(--m);
cordinate++;
votes++;
}
cout << votes << endl;
}
}