Careercup - Google面试题 - 4699414551592960
2014-05-06 13:59
330 查看
2014-05-06 13:34
题目链接
原题:
题目:有一队人正在排队,告诉你每个人的姓名、身高(目前默认都不相同),以及他/她所看到的前面比他高的人。请你计算出这个队伍里各个人的顺序。
解法:从最矮的人入手。对于最矮的人,他所看到的所有人都比他高,所以如果他看到有K个人比他高,那么他一定排在K + 1名。我的代码是当时琢磨了很久,采用树状数组写出来的。此处的树状数组提供快速修改区间、查询单个元素的能力,能做到对数时间。现在居然已经忘了当时的具体思路。总体思想是先按身高升序排序,然后逐个确定每个人在队列里的位置。关键的一点:每次都只能确定当前最矮的人排在哪儿。树状数组中维护的值c[i]的意义,是记录当前位置的前面有多少个比它高。其中还有个方法用到二分搜索,所以整体复杂度是比较奇怪的O(n * log(n) + n * log^2(n)) = O(n * log^2(n))。
代码:
题目链接
原题:
we have a random list of people. each person knows his own height and the number of tall people in front of him. write a code to make the equivalent queue. for example : input: <"Height","NumberOfTall","Name">, <6,2,"A">,<1,4,"B">,<11,0,"C">,<5,1,"D">,<10,0,"E">,<4,0,"F"> output: "F","E","D","C","B","A" --> end of queue
题目:有一队人正在排队,告诉你每个人的姓名、身高(目前默认都不相同),以及他/她所看到的前面比他高的人。请你计算出这个队伍里各个人的顺序。
解法:从最矮的人入手。对于最矮的人,他所看到的所有人都比他高,所以如果他看到有K个人比他高,那么他一定排在K + 1名。我的代码是当时琢磨了很久,采用树状数组写出来的。此处的树状数组提供快速修改区间、查询单个元素的能力,能做到对数时间。现在居然已经忘了当时的具体思路。总体思想是先按身高升序排序,然后逐个确定每个人在队列里的位置。关键的一点:每次都只能确定当前最矮的人排在哪儿。树状数组中维护的值c[i]的意义,是记录当前位置的前面有多少个比它高。其中还有个方法用到二分搜索,所以整体复杂度是比较奇怪的O(n * log(n) + n * log^2(n)) = O(n * log^2(n))。
代码:
// http://www.careercup.com/question?id=4699414551592960 #include <algorithm> #include <iostream> #include <string> #include <vector> using namespace std; struct Person { int height; int taller; string name; Person(int _height = 0, int _taller = 0, string _name = ""): height(_height), taller(_taller), name(_name) {}; bool operator < (const Person &other) { return this->height < other.height; }; friend ostream& operator << (ostream &cout, const Person &p) { cout << '<'<< p.name << p.height << '>'; return cout; }; }; template <class T> class BinaryIndexedTree { public: BinaryIndexedTree(int _n = 0): n(_n), v(_n + 1) {}; int size() { return n; }; void addAll(int x, const T &val) { while (x >= 1 && x <= n) { v[x] += val; x -= lowBit(x); } }; void addInterval(int x, int y, const T &val) { addAll(x - 1, -val); addAll(y, val); }; void clear() { v.resize(1); n = 0; }; void resize(int new_n) { v.resize(new_n + 1); n = new_n; } T sum(int x) { T res = 0; while (x >= 1 && x <= n) { res += v[x]; x += lowBit(x); } return res; }; int lowerBound(const T &val) { int ll, mm, rr; if (n == 0) { return 0; } T res; if (val <= (res = sum(1))) { return 1; } if (val > (res = sum(n))) { return n + 1; } ll = 1; rr = n; while (rr - ll > 1) { mm = (ll + rr) / 2; res = sum(mm); if (val > res) { ll = mm; } else { rr = mm; } } return rr; } private: vector<T> v; int n; int lowBit(int x) { return x & -x; }; }; int main() { vector<Person> people; vector<int> queue; BinaryIndexedTree<int> bit; int i, j; int n; while (cin >> n && n > 0) { people.resize(n); for (i = 0; i < n; ++i) { cin >> people[i].height >> people[i].taller >> people[i].name; } sort(people.begin(), people.end()); bit.resize(n); queue.resize(n); for (i = 1; i <= n; ++i) { bit.addInterval(i, n, 1); } for (i = 1; i <= n; ++i) { j = bit.lowerBound(people[i - 1].taller + 1); queue[j - 1] = i; bit.addInterval(j, n, -1); } for (i = 0; i < n; ++i) { cout << people[queue[i] - 1]; } cout << endl; people.clear(); queue.clear(); bit.clear(); } return 0; }
相关文章推荐
- Careercup - Google面试题 - 5424071030341632
- Careercup - Google面试题 - 5680330589601792
- Careercup - Google面试题 - 4877486110277632
- Careercup - Google面试题 - 5085331422445568
- Careercup - Google面试题 - 4716965625069568
- Careercup - Google面试题 - 5162732873580544
- Careercup - Google面试题 - 4807591515389952
- Careercup - Google面试题 - 6283958983589888
- Careercup - Google面试题 - 5661939564806144
- Careercup - Google面试题 - 6271724635029504
- Careercup - Google面试题 - 6253551042953216
- Careercup - Google面试题 - 5727310284062720
- Careercup - Google面试题 - 5724823657381888
- Careercup - Google面试题 - 6407924087783424
- Careercup - Google面试题 - 5765091433644032
- Careercup - Google面试题 - 5634470967246848
- Careercup - Google面试题 - 4847954317803520
- Careercup - Google面试题 - 4557716425015296
- Careercup - Google面试题 - 5732809947742208
- Careercup - Google面试题 - 5735304249999360