个人学习记录,代码难免不尽人意
Sample Input:
10
6666 5551 5552 1 7777 1 100
1234 5678 9012 1 0002 2 300
8888 -1 -1 0 1 1000
2468 0001 0004 1 2222 1 500
7777 6666 -1 0 2 300
3721 -1 -1 1 2333 2 150
9012 -1 -1 3 1236 1235 1234 1 100
1235 5678 9012 0 1 50
2222 1236 2468 2 6661 6662 1 300
2333 -1 3721 3 6661 6662 6663 1 100
Sample Output:
3
8888 1 1.000 1000.000
0001 15 0.600 100.000
5551 4 0.750 100.000
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct node{int m=0,a=0;
}Node[10010];
struct result{int id;int num;double avgm,avga;
};
int dad[10010];
int findfather(int n){if(dad[n]==n) return n;else findfather(dad[n]);
}
bool cmp(result a,result b){if(a.avga!=b.avga) return a.avga>b.avga;else return a.id<b.id; //不要忘记加return
}
vector<int> root;
int main(){int n;scanf("%d",&n);for(int i=0;i<10010;i++){dad[i]=i;}for(int i=0;i<n;i++){int id,father,mother,k;scanf("%d %d %d %d",&id,&father,&mother,&k);int arr[k+3];arr[0]=id;arr[1]=father;arr[2]=mother;for(int j=3;j<k+3;j++){scanf("%d",&arr[j]);}bool flag=true;int f;for(int j=0;j<k+3;j++){if(findfather(arr[j])!=arr[j]&&arr[j]!=-1){flag=false;f=findfather(arr[j]);break;}}if(flag){root.push_back(arr[0]);for(int j=0;j<k+3;j++){if(arr[j]!=-1)dad[findfather(arr[j])]=dad[arr[0]];}}else{for(int j=0;j<k+3;j++){if(arr[j]!=-1)dad[findfather(arr[j])]=f;}}int m,a;scanf("%d %d",&m,&a);node no;no.m=m;no.a=a;Node[id]=no;}vector<int> temp;for(int i=0;i<root.size();i++){if(findfather(root[i])==root[i])temp.push_back(root[i]);}root=temp;
// for(int i=0;i<root.size();i++){
// cout << root[i] <<endl;
// }
// cout << "end";vector<result> v;for(int i=0;i<root.size();i++){int r=root[i];int minid=10010;int sm=0,sa=0;int num=0;for(int j=0;j<10010;j++){if(findfather(dad[j])==r){num++;if(j<minid) minid=j;sm+=Node[j].m;sa+=Node[j].a;}}double avgm=sm/(1.0*num),avga=sa/(1.0*num);//这个地方必须将除数变为double再相除,否则得不到正确答案。 result res;res.id=minid;res.num=num;res.avgm=avgm;res.avga=avga;v.push_back(res);}sort(v.begin(),v.end(),cmp);printf("%d\n",v.size());for(int i=0;i<v.size();i++){printf("%04d %d %.3lf %.3lf\n",v[i].id,v[i].num,v[i].avgm,v[i].avga);}
}
这道题我采用并查集来做而不是二叉树,因为我考虑到数据量可能比较庞大用二叉树模拟可能会超时。这道题本身不算难,但是暴露出的我的问题还是蛮多的:
①:忘记写return了
②:如果要求double=int/int,最好是将int都转换成double来做。
③:我的做法是无视父母节点和孩子节点,都将他们连接到一起,但是这样做会造成取得了多余的root节点,因此我们在遍历完毕之后需要再循环判断一次这些节点还是不是root节点(不是root节点的点在遍历后father就发生改变了),这样才能保证最后的正确。
这道题还是比较有价值的,值得动手一试。