zoukankan      html  css  js  c++  java
  • A1114 Family Property (25分)

    一、技术总结

    1. 这题考查内容为并查集,核心是用一个数组存储当前结点的父节点编号,操作有初始化、查找、合并。
    2. 题意首先理解一下,题目意思是给出N行,然后每行中首先给出自己的ID号、然后是父亲ID、再是母亲ID,如果父亲跟母亲已经去世,该ID好给出为-1,然后再给数字num,代表给人的孩子数,后面跟上num个孩子的ID号,最后是这个人拥有房子的数量和总面积。最后要求是如果是有直接或间接关系的归为一个家庭,然后求出该家庭的平均房子数量,和平均面积都保留三位小数。输出结果按照平均面积降序输出,如果一样则按各自家庭中最小ID号升序输出。
    3. 首先应该定义一个father数组用于并查集操作,同时设置一个visit数组用于存储所有有效结点。在其实在读取每行的时候就可以进行合并操作,这里有一点需要注意一下,因为题目要求是给出每个家庭成员中的最小ID号来代表该家庭,所以合并时,应该直接将ID号较小的作为父节点。
    4. 我们设置Data结构体用于存储每行的数据,用这是node结构体用于存储将要输出的家庭,里面包含ID号、家庭人数、平均房子数量、平均住房面积、还有标志位flag用于查看该ID号是否为有效家庭,即用于统计家庭数量。通过遍历data中的每行,最小家庭号直接用查找函数查找有其父节点,同时也加上该成员的住房面积和房子数量。而成员数量通过之前的visit数组遍历,有效结点分别归属于哪一个家庭。这时统计cnt也就是家庭数量。
    5. 最后统计完成后,计算出平均住房面积、数量,再使用sort函数排序,最后输出结果。

    二、参考代码

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXV = 1010;
    const int MAXN = 10000;
    struct Data{
    	int id, fid, mid;
    	int num, area;
    	int kid[10];
    }data[MAXV];
    struct node{
    	int id, people;
    	double num, area;
    	bool flag = false;
    }ans[MAXN];
    bool visit[MAXN];
    int father[MAXN];
    int findFather(int x){
    	int a = x;
    	while(x != father[x]){
    		x = father[x];
    	}
    	while(a != father[a]){
    		int z = a; 
    		a = father[a];
    		father[z] = x;
    	}
    	return x;
    }
    void Union(int a, int b){
    	int faA = findFather(a);
    	int faB = findFather(b);
    	if(faA > faB){
    		father[faA] = faB;
    	}else if(faA < faB){
    		father[faB] = faA;
    	}
    }
    bool cmp(node a, node b){
    	if(a.area != b.area){
    		return a.area > b.area;
    	}else{
    		return a.id < b.id;
    	}
    }
    int main(){
    	int n, k, cnt = 0;
    	scanf("%d", &n);
    	for(int i = 0; i < 10000; i++){
    		father[i] = i;
    	}
    	for(int i = 0; i < n; i++){
    		scanf("%d %d %d %d", &data[i].id, &data[i].fid, &data[i].mid, &k);
    		visit[data[i].id] = true;
    		if(data[i].fid != -1){
    			visit[data[i].fid] = true;
    			Union(data[i].id, data[i].fid);
    		}
    		if(data[i].mid != -1){
    			visit[data[i].mid] = true;
    			Union(data[i].id, data[i].mid);
    		}
    		for(int j = 0; j < k; j++){
    			scanf("%d", &data[i].kid[j]);
    			visit[data[i].kid[j]] = true;
    			Union(data[i].id, data[i].kid[j]);
    		}
    		scanf("%d %d", &data[i].num, &data[i].area);
    	}
    	for(int i = 0; i < n; i++){
    		int id = findFather(data[i].id);
    		ans[id].id = id;
    		ans[id].num += data[i].num;
    		ans[id].area += data[i].area;
    		ans[id].flag = true;
    	}
    	for(int i = 0; i < MAXN; i++){
    		if(visit[i]){
    			int id = findFather(i);
    			ans[id].people++;
    		}
    		if(ans[i].flag){
    			cnt++;
    		}
    	}
    	for(int i = 0; i < MAXN; i++){
    		if(ans[i].flag){
    			ans[i].num = (double)(ans[i].num * 1.0 / ans[i].people);
    			ans[i].area = (double)(ans[i].area * 1.0 / ans[i].people);
    		}
    	}
    	sort(ans, ans+MAXN, cmp);
    	printf("%d
    ", cnt);
    	for(int i = 0; i < cnt; i++){
    		printf("%04d %d %.3f %.3f
    ", ans[i].id, ans[i].people, ans[i].num, ans[i].area);
    	} 
    	return 0;
    }
    
    作者:睿晞
    身处这个阶段的时候,一定要好好珍惜,这是我们唯一能做的,求学,钻研,为人,处事,交友……无一不是如此。
    劝君莫惜金缕衣,劝君惜取少年时。花开堪折直须折,莫待无花空折枝。
    曾有一个业界大牛说过这样一段话,送给大家:   “华人在计算机视觉领域的研究水平越来越高,这是非常振奋人心的事。我们中国错过了工业革命,错过了电气革命,信息革命也只是跟随状态。但人工智能的革命,我们跟世界上的领先国家是并肩往前跑的。能身处这个时代浪潮之中,做一番伟大的事业,经常激动的夜不能寐。”
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    有注释的LED驱动
    给想成为程序员的大学生的建议
    三星s3c6410用户手册初步阅读
    linux下重新安装grub
    对寄存器的操作
    linux 头文件
    VC的环境设置
    VC++工程文件说明
    C/C++文件操作转载自http://www.cnblogs.com/kzloser/archive/2012/07/16/2593133.html#b1_2
    GetWindowDC-BeginPaint-GetDC 区别详解
  • 原文地址:https://www.cnblogs.com/tsruixi/p/12989314.html
Copyright © 2011-2022 走看看