题目描述:https://www.1point3acres.com/bbs/thread-225621-1-1.html
这道题是Bloomberg经典面试题,和LRU非常类似。维护一个list记录runner的顺序,一旦有runner经过sensor,我们就需要调整位置。本质其实就是要写一个 update(runner i, sensor j) 的函数。
注意C++中 list.splice 函数,由于对同一个list进行操作,指针不会失效,仍指向原来的list元素,runner2pos 也不用更新。
// https://www.1point3acres.com/bbs/thread-225621-1-1.html class Marathon{ int m, n; // m runner with id 1-m, n sensor with id 1-n list<int> l; // record order of all runners vector<list<int>::iterator> runner2pos; // runner_id -> the pos in list vector<int> passedSensor; // runner_id -> record how many sensors have been passed vector<int> firstPassed; // sensor_id -> the first runner who passed the sensor public: Marathon(int _m, int _n){ m = _m; n = _n; runner2pos.resize(m+1); passedSensor.resize(m+1,0); firstPassed.resize(n+1,0); firstPassed[0] = 1; // at first in the order of 1~m for (int i=1;i<=m;++i) l.push_back(i); for (auto it=l.begin();it!=l.end();++it){ runner2pos[distance(l.begin(),it)+1]=it; // cout << distance(l.begin(),it)+1 << ' ' << *it << endl; } } void passMilestone(int runner_id){ int sensor_id = ++passedSensor[runner_id]; if (firstPassed[sensor_id]==0) firstPassed[sensor_id]=runner_id; // runner_id passed sensor_id, insert this runner to the front of previous sensor auto cur_pos=runner2pos[runner_id]; auto new_pos=runner2pos[firstPassed[sensor_id-1]]; l.splice(new_pos,l,cur_pos); } void printLeadBoard(){ for (auto x:l) cout<<x<<' '; cout << endl; } }; int main() { Marathon m(3,2); m.passMilestone(3); // runner 3 passed sensor 1 m.printLeadBoard(); m.passMilestone(2); // runner 2 passed sensor 1 m.printLeadBoard(); m.passMilestone(2); // runner 2 passed sensor 2 m.printLeadBoard(); return 0; }