Title Description: https://www.1point3acres.com/bbs/thread-225621-1-1.html
This question is Bloomberg classic face questions, and LRU very similar. Maintain order in a list of record runner, once a runner through the sensor, we need to adjust the position. In fact, the essence is to write a update (runner i, sensor j) function.
Note that in C ++ list.splice function, due to operate on the same list, the pointer will not fail, still pointing to the original list of elements, runner2pos do not update.
// 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; }