zoukankan      html  css  js  c++  java
  • Careercup

    2014-05-06 13:34

    题目链接

    原题:

    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))。

    代码:

      1 // http://www.careercup.com/question?id=4699414551592960
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <string>
      5 #include <vector>
      6 using namespace std;
      7 
      8 struct Person {
      9     int height;
     10     int taller;
     11     string name;
     12     Person(int _height = 0, int _taller = 0, string _name = ""): 
     13         height(_height), taller(_taller), name(_name) {};
     14     bool operator < (const Person &other) {
     15         return this->height < other.height;
     16     };
     17     
     18     friend ostream& operator << (ostream &cout, const Person &p) {
     19         cout << '<'<< p.name << p.height << '>';
     20         return cout;
     21     };
     22 };
     23 
     24 template <class T>
     25 class BinaryIndexedTree {
     26 public:
     27     BinaryIndexedTree(int _n = 0): n(_n), v(_n + 1) {};
     28     
     29     int size() {
     30         return n;
     31     };
     32     
     33     void addAll(int x, const T &val) {
     34         while (x >= 1 && x <= n) {
     35             v[x] += val;
     36             x -= lowBit(x);
     37         }
     38     };
     39     
     40     void addInterval(int x, int y, const T &val) {
     41         addAll(x - 1, -val);
     42         addAll(y, val);
     43     };
     44     
     45     void clear() {
     46         v.resize(1);
     47         n = 0;
     48     };
     49     
     50     void resize(int new_n) {
     51         v.resize(new_n + 1);
     52         n = new_n;
     53     }
     54     
     55     T sum(int x) {
     56         T res = 0;
     57         while (x >= 1 && x <= n) {
     58             res += v[x];
     59             x += lowBit(x);
     60         }
     61         
     62         return res;
     63     };
     64     
     65     int lowerBound(const T &val) {
     66         int ll, mm, rr;
     67         
     68         if (n == 0) {
     69             return 0;
     70         }
     71 
     72         T res;
     73         if (val <= (res = sum(1))) {
     74             return 1;
     75         }
     76         if (val > (res = sum(n))) {
     77             return n + 1;
     78         }
     79         
     80         ll = 1;
     81         rr = n;
     82         while (rr - ll > 1) {
     83             mm = (ll + rr) / 2;
     84             res = sum(mm);
     85             if (val > res) {
     86                 ll = mm;
     87             } else {
     88                 rr = mm;
     89             }
     90         }
     91         
     92         return rr;
     93     }
     94 private:
     95     vector<T> v;
     96     int n;
     97     
     98     int lowBit(int x) {
     99         return x & -x;
    100     };
    101 };
    102 
    103 int main()
    104 {
    105     vector<Person> people;
    106     vector<int> queue;
    107     BinaryIndexedTree<int> bit;
    108     int i, j;
    109     int n;
    110     
    111     while (cin >> n && n > 0) {
    112         people.resize(n);
    113         for (i = 0; i < n; ++i) {
    114             cin >> people[i].height >> people[i].taller >> people[i].name;
    115         }
    116         sort(people.begin(), people.end());
    117         bit.resize(n);
    118         queue.resize(n);
    119         for (i = 1; i <= n; ++i) {
    120             bit.addInterval(i, n, 1);
    121         }
    122         for (i = 1; i <= n; ++i) {
    123             j = bit.lowerBound(people[i - 1].taller + 1);
    124             queue[j - 1] = i;
    125             bit.addInterval(j, n, -1);
    126         }
    127         for (i = 0; i < n; ++i) {
    128             cout << people[queue[i] - 1];
    129         }
    130         cout << endl;
    131         
    132         people.clear();
    133         queue.clear();
    134         bit.clear();
    135     }
    136     
    137     return 0;
    138 }
  • 相关阅读:
    列表和元组
    UVM宏
    UVM中重要函数
    组合模式(composite)
    装饰器模式(Decorator)
    适配器模式(Adapter)
    桥接模式
    原型模式(prototype)
    单例模式(singleton)
    UML类图
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3711401.html
Copyright © 2011-2022 走看看