Line reconstruction by height

73 篇文章 1 订阅
8 篇文章 0 订阅

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值