这个题我做了好久,终于用自己的思路Ac了/doge
把每个人做一个集合,其实可以把id,num,house,area,pre这几个数组变成该成这种
class Person {
public:
int id, num, area, house, pre;
}person[maxn];
对人进行合并操作,每次插入一个人判断这个人是否存在,也就是他的id是否存在,id存在则增加一个人否则不加人只合并,
每次通过find和对minid和person的比较进行合并,只保留其中最高级下表较小的,这样就保证了最后的num不为0的人的id满足要求。这里有个坑点就是把两个下标一样的合并时,由于要被合并者置零,会导致最后很多家庭的全部成员死于莫名AOE,
所以这是应该不操作。
最后把num不为0的人储存在一个vector里,按要求排个序,在输出就可以了。
可以看到速度还是不慢的。
代码如下::
#include<iostream>
#include<cstring>
#include<ctime>
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 10005
int id[maxn], num[maxn], house[maxn], area[maxn], pre[maxn];
typedef struct Ans {
int id;
int num;
double house;
double area;
Ans(int id, int num, int house, int area) {
this->id = id;
this->num = num;
this->house = 1.0*house / num;
this->area = 1.0*area / num;
}
void print() {
printf("%04d %d %.3lf %.3lf\n", id, num, house, area);
}
};
int find(int i) {
if (pre[i] == i)return i;
else {
return i=find(pre[i]);
}
}
int un(int number, int minid) {
if (number != -1) {
if (id[number]) {
id[number] = 0;
if (number != pre[number]) {
number = find(number);
}
num[number]++;
}
else {
if (number != pre[number]) {
number = find(number);
}
}
if (number < minid) {//合并number和minid
num[number] += num[minid];
house[number] += house[minid];
area[number] += area[minid];
num[minid] = 0;
house[minid] = 0;
area[minid] = 0;
pre[minid] = number;
minid = number;
}
else if(number>minid){
num[minid] += num[number];
house[minid] += house[number];
area[minid] += area[number];
num[number] = 0;
house[number] = 0;
area[number] = 0;
pre[number] = minid;
}
}
return minid;
}
vector<Ans> ans;
bool cmp(const Ans a, const Ans b) {
if (a.area == b.area)return a.id < b.id;
return a.area > b.area;
}
int main(int argc,char argv[]) {
int minid;
int t;//numOfHouses
int k;//numOfKids
int number;//numberOfPerson
int s;//areas
int n;//house
cin >> t;
for (int i = 0; i < maxn; i++) {
pre[i] = i;
num[i] = 0;
id[i] = 1;
}
while (t--) {
cin >> minid;
if (id[minid]) {
id[minid] = 0;
if (minid != pre[minid]) {
minid = find(minid);
}
num[minid]++;
}
else {
if (minid != pre[minid]) {
minid = find(minid);
}
}
cin >> number;
if(number!=-1)
minid = un(number, minid);
cin >> number;
if (number!=-1)
minid = un(number, minid);
cin >> k;
while (k--) {
cin >> number;
if (number!=-1)
minid = un(number, minid);
}
cin >> n >> s;
area[minid] += s;
house[minid] += n;
}
int x ;
for (int i = 0; i < maxn; i++) {
if (num[i] != 0) {
x = find(i);
if (x < i) {
un(i, x);
}
else {
un(x, i);
}
}
}
for (int i = 0; i < maxn; i++) {
if (num[i] != 0) {
ans.push_back(Ans(i, num[i], house[i], area[i]));
}
}
printf("%d\n", ans.size());
sort(ans.begin(), ans.end(), cmp);
for (Ans i : ans) {
i.print();
}
return 0;
}