//952K 3094MS C++
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int MAX = 30010;
struct Employee {
int ID;
int height;
int salary;
int subordinatesNum;
int parentPos;
int nextBroPos;
};
typedef struct Employee Employee;
int cmp(const void * a, const void * b) {
return (*((Employee *)b)).salary - (*((Employee *)a)).salary;
}
Employee employees[MAX];
int childListHead[MAX];
int caseNum;
int employeedNum;
int queryNum;
int IDMap[999999];
void addInTree(int parentPos, Employee & curEmpolyee, int curEmpolyeePos) {
employees[parentPos].subordinatesNum++;
int curChildPos = childListHead[parentPos];
// add as child's child
while(curChildPos) {
const Employee & curChildEmplyee = employees[curChildPos];
if (curChildEmplyee.salary > curEmpolyee.salary &&
curChildEmplyee.height >= curEmpolyee.height) {
addInTree(curChildPos, curEmpolyee, curEmpolyeePos);
return;
}
curChildPos = employees[curChildPos].nextBroPos;
}
// add as parent's child
curEmpolyee.parentPos = parentPos;
curEmpolyee.nextBroPos = childListHead[parentPos];
childListHead[parentPos] = curEmpolyeePos;
}
int main() {
scanf("%d", &caseNum);
for (int i = 1; i <= caseNum; i++) {
scanf("%d %d", &employeedNum, &queryNum);
memset(childListHead, 0, sizeof(childListHead));
memset(employees, 0, sizeof(employees));
memset(IDMap, 0xff, sizeof(IDMap));
for (int j = 0; j < employeedNum; j++) {
scanf("%d %d %d",&(employees[j].ID),
&(employees[j].salary),
&(employees[j].height));
}
qsort(employees, employeedNum, sizeof(Employee), cmp);
for (int j = 0; j < employeedNum; j++) {
IDMap[employees[j].ID] = j;
}
int rootPos = 0;
employees[rootPos].parentPos = -1;
for (int j = 1; j < employeedNum; j++) {
addInTree(rootPos, employees[j], j);
}
for (int j = 1; j <= queryNum; j++) {
int queryId;
scanf("%d", &queryId);
// for (int k = 0; k < employeedNum; k++) {
// if (employees[k].ID == queryId) {
// int parentId = 0;
// if (employees[k].parentPos != -1) {
// parentId = employees[employees[k].parentPos].ID;
// }
// printf("%d %d\n", parentId, employees[k].subordinatesNum);
// }
// }
int parentId = 0;
if (employees[IDMap[queryId]].parentPos != -1) {
parentId = employees[employees[IDMap[queryId]].parentPos].ID;
}
printf("%d %d\n", parentId, employees[IDMap[queryId]].subordinatesNum);
}
}
}
考察的应该是建造一颗多叉树, 不过我用这种思路做,竟然3000+ms, 而另外一种类似于枚举的竟然只有94ms......
http://blog.csdn.net/neofung/article/details/7654076
后来搜了一下,貌似只要用多叉树做的,不进行特别优化的话,好像至少都是1000+向上。
用多叉树的思想比较简单:
首先在输入完以后,按照salary进行从大到小排序,那么第一个一定是boss,
然后以其为根, 将后面的employee插入到这棵树中,
如果当前的employee的salary (小于)和 height (小于等于) 当前根的某个child, 那么再递归的将该employee插入到该child,
直到到达某个节点,没有child, 或者所有child不满足上面的关系,那么将此employee作为此节点的child插入,更新其parentId,
同时在插入的过程中,更新每个父节点的childNum。
最后查询时,遍历所有的employee,找到和queryID相同employee,输出其parentId和 childNum(本来以为遍历费劲,后来专门搞了一个map来映射ID到 数组位置,还是3000+ms....)