题目大意:

n个人是朋友,他们坐在一排去看电影,相邻的最多三个人可以吃同一桶爆米花。每个人都想迟到爆米花,问最少需要几桶爆米花?

输入:一个数组,代表这n个人每个人选择的座位号。

输出:最少几桶爆米花

数据范围:0<n<=100,0<=a[i]<1000

解题报告:

一题多解。这题是模拟,但是有无数种模拟的方式,我看到数据范围第一反应就是如下的模拟方式:

新建一个数组保存每个位置上是否有人坐。然后从小到大遍历这个数组维护答案就可以了。

注意写的时候不能【当前位置cur有人则直接考虑cur+3的位置】,因为如果是【有,无,有】这种情况,其实是应该买两桶爆米花的。

再就是一些细节问题,比如while循环结束的时候,cur得到的是可行的最后一个位置,还是可行解的下一个位置。

时间复杂度O(n)。

思考:如果这题数据范围改成n<1e5, a[i]<1e9,那就不能做什么做了。应该是对原数组排序然后再遍历。复杂度O(nlogn)可解。

AC代码:

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

int checkNeighboring(std::vector<int> seatNumbers) {
int maxx = 0;
for(int i = 0; i<seatNumbers.size(); i++) {
maxx = std::max(seatNumbers[i], maxx);
}
std::vector<bool> vv(maxx + 1, false);
for(int i = 0; i<seatNumbers.size(); i++) {
vv[seatNumbers[i]] = true;
}
int cur = 0;
int ans = 0;
while(cur <=maxx) {
if(vv[cur] == true) {
ans ++;
int up = std::min(cur+2, maxx);
while(cur <= up && vv[cur]) cur ++;
cur--;
}
cur += 1;
}
return ans;
}

int main()
{
vector<int> t1;
t1.push_back(1);
t1.push_back(2);
t1.push_back(3);
t1.push_back(4);
t1.push_back(10);
cout << checkNeighboring(t1) << endl;

vector<int> t2;
t2.push_back(1);
t2.push_back(3);
t2.push_back(4);
t2.push_back(7);
t2.push_back(8);
t2.push_back(10);
cout << checkNeighboring(t2) << endl;

vector<int> t3;
t3.push_back(4);
t3.push_back(8);
t3.push_back(7);
t3.push_back(5);
t3.push_back(6);
cout << checkNeighboring(t3) << endl;
return 0;
}