Problem
Suppose you have a line of n people in which the k-th
person is described by a pair (h,t)
, where h is the height of the k-th
person and t is the number of people in front of k
who have a height greater or equal than h
. Write an algorithm to reconstruct the line.
For example, if the line is composed by the following people:
[(7, 0, A),(4, 4, B),(7, 1, C), (5, 0, D), (6, 1, E), (5, 2, F)]
The original line should be:
[(5, 0, D), (7, 0, A), (5, 2, F), (6, 1, E), (4, 4, B),(7, 1, C)]
Solution
每个输入信息表示为: (height, taller_num, name), 两种思路:
1. 排序:先以taller_num
升序排序,如果相等按照height
的降序排列。然后将每个人插入到他们正确的位置,遍历每一个人 p,从结果list的开头计数比p.height大的数目,直到与p.taller_num为止,即找到p在res中的位置,将p插入到当前位置。
2. 先以height
的降序排列,如果相等按照taller_num
的升序排列。然后依然是找到每个人的正确位置插入, 不过这次要简单一些,遍历每个人(p
), 将其插入list.begin() + p.taller_num
位置。
Code
#include <iostream>
#include <vector>
#include <list>
#include <string>
using namespace std;
struct person{
string name;
int height;
int taller_num;
person(string name, int h, int num) : name(name), height(h), taller_num(num){}
};
bool cmp(person& p1, person& p2) {
if(p1.taller_num != p2.taller_num)
return p1.taller_num < p2.taller_num;
return p1.height > p2.height;
}
void reorder(vector<person>& person_list, list<person>& res) {
sort(person_list.begin(), person_list.end(), cmp);
for(int i = 0; i < person_list.size(); ++i) {
list<person>::iterator iter = res.begin();
int n = person_list[i].taller_num;
while(n > 0) {
if(iter->height >= person_list[i].height)
--n;
++iter;
}
res.insert(iter, person_list[i]);
}
}
bool cmp2(person& p1, person&p2) {
if(p1.height != p2.height) return p1.height > p2.height;
return p1.taller_num < p2.taller_num;
}
void reorder2(vector<person>& person_list, list<person>& res) {
sort(person_list.begin(), person_list.end(), cmp2);
for(auto& p : person_list) {
list<person>::iterator iter = res.begin();
int n = p.taller_num;
while(n-- > 0) {
++iter;
}
res.insert(iter, p);
}
}
int main() {
vector<person> person_list;
person_list.push_back(person("A", 7, 0));
person_list.push_back(person("B", 4, 4));
person_list.push_back(person("C", 7, 1));
person_list.push_back(person("D", 5, 0));
person_list.push_back(person("E", 6, 1));
person_list.push_back(person("F", 5, 2));
list<person> res;
reorder(person_list, res);
for(person& p : res) {
cout << p.name << " ";
}
cout << endl;
res.clear();
cout << "reorder2 :" << endl;
reorder2(person_list, res);
for(person& p : res) {
cout << p.name << " ";
}
cout << endl;
}