题目:给一个数n,之后说明n个人财产情况,格式为 人员编号 父编号 母编号 孩子个数 数个孩子编号--- 房产数量 房产面积
虽然让求出有多少个家族及家族平均财产情况,输出为
家族编号最小成员 家族人数 平均房山数(三位小数) 平均面积(三位小时)
之前显是在输入上卡了很久double和float的输入均为%f不是%lf!!
输出也要注意
printf("%04d %d %.3lf %.3lf\n", v2[i].n, v2[i].num, v2[i].s, v2[i].a);
还有初始化的问题
struct node {
int num;
int n;
double s;
float a;
node() { //这样可以对新建的进行初始化
num = 1;
s = 0;
a = 0;
}
}v[10005];
思路问题,乍一看知道是并查集,但又比较麻烦,显示把家族合并,然后把财产先归到个人,最后遍历,把财产加给那个最小的成员(也就是祖先),最后计算平均排序
int zu[10005];
int pan[10005];
struct node {
int num;
int n;
double s;
float a;
node() { //这样可以对新建的进行初始化
num = 1;
s = 0;
a = 0;
}
}v[10005]; //这样创建可以创建一系列已经被初始化的node
int qiuzu(int a)
{
if (zu[a] != a)
return zu[a] = qiuzu(zu[a]);
else
return a;
}
void marge(int a, int b)
{
int p1 = qiuzu(a);
int p2 = qiuzu(b);
if (p1 < p2) //把祖先定为最小的那个
zu[p2] = p1;
else
zu[p1] = p2;
}
bool cmp(node a, node b)
{
if (a.a > b.a)
return true;
if (a.a == b.a&&a.n < b.n)
return true;
return false;
}
int main(void)
{
int n, i, j;
scanf("%d", &n);
for (i = 0;i < 10000;i++)
zu[i] = i;
for (i = 0;i < n;i++)
{
int a, b, c, mi;
scanf("%d%d%d", &a, &b, &c); //接受自己和爸妈
pan[a] = 1; //证明该人存在
if (b != -1) //爸妈存在则合并家庭
{
marge(a, b);
pan[b] = 1;
}
if (c != -1)
{
marge(a, c);
pan[c] = 1;
}
int n2;
scanf("%d", &n2);
for (j = 0;j < n2;j++) //接受孩子并合并孩子
{
int d;
scanf("%d", &d);
marge(a, d);
pan[d] = 1;
}
scanf("%f%f", &v[a].s, &v[a].a); //把所有房产算到本人头上,这里卡了一下,之前不小心写成%lf就乱码
}
set<int> s;
for (i = 9999;i >= 0;i--)
{
if (pan[i] == 1)
{
int x = qiuzu(i);
s.insert(x); //把最小的家族人员打入
if (x != i) //从后向前遍历,把所有的财产算到祖先头上(祖先数最小的那个
{
v[x].num += v[i].num; //就算该人财产为0,单因为已经初始化,所以不会乱码
v[x].s += v[i].s;
v[x].a += v[i].a;
}
}
}
set<int>::iterator it;
vector<node> v2;
for (it = s.begin();it != s.end();it++) //遍历家族,并求出人均财产
{
v[*it].s = v[*it].s / v[*it].num;
v[*it].a = v[*it].a / v[*it].num;
v[*it].n = *it;
v2.push_back(v[*it]);
}
sort(v2.begin(), v2.end(), cmp);
printf("%d\n", v2.size());
for (i = 0;i < v2.size();i++)
{
printf("%04d %d %.3lf %.3lf\n", v2[i].n, v2[i].num, v2[i].s, v2[i].a); //注意输出格式
}
return 0;
}