【并查集】详解之L2-007 家庭房产 (25分)附:printf()详细介绍

思路:

  1. 利用并查集的思想,把每一位成员进行分类,同一个家庭的分在一起,并以每行第一个人为领导;
  2. 再进行暴力枚举,对每个家庭的信息进行处理。
  3. 其中关键是并查集的思想、sort函数快速排序的使用和printf函数控制输出

 详细得在代码有解释~~

#include<iostream>
#include<algorithm>
#include<iomanip>
#include<string>
#include<string.h>
#include<stdio.h>
using namespace std;
struct node//表示人员的节点
{
	int hnum;//房产数量
	int area;//房产面积
	node() { hnum = area = 0; }
};
struct Ans//表示家庭的节点
{
	int id, num;
	double avehnum, avearea;
	bool operator <(Ans &b)//家庭信息按人均面积降序输出,若有并列,则按成员编号升序输出
	{
		if (b.num*avearea == num * b.avearea)//本来是除法,变换一下换成乘法
			return id < b.id;//从大到小a>b,从小到大a<b(用于下面的sort函数)
		else
			return b.num*avearea > num*b.avearea;
	}
};
//bool  cmp(Ans a, Ans b) {
	//if (a.id != b.score)
	//return a.id > b.id;//从大到小a>b,从小到大a<b 
//else return strcmp(a.name, b.name) < 0;//strcmp是string.h头文件下用来比较两个char型字符串的字典序大小,
//str1小于str2返回负数 
//}
node a[10010];//成员
int f[10010];//并查集记录
Ans ans[10010];//家庭
bool vis[10010], vv[10010];
//并查集的两个函数find、 merge
int Find(int x)
{
	if (x == f[x])//x是它自己本身,说明他是这个集合的领导
		return x;
	else
	{
		f[x] = Find(f[x]);//深度遍历,找到最终的领导
		return f[x];
	}
}
void Merge(int x, int y)
{
	x = Find(x);
	y = Find(y);
	if (x != y)
	{
		f[y] = x;//让x变成y的领导
	}
}
void init()
{
	memset(vis, 0, sizeof(vis));
	memset(vis, 0, sizeof(vis));
	for (int i = 0; i < 10000; i++)//初始化并查集
	{
		f[i] = i;
	}
}


int main()
{
	int n, k, zd, fd, md, cd;
	cin >> n;
	init();
	for (int i = 0; i < n; i++)//将家庭成员合并在一起
	{
		cin >> zd >> fd >> md;//本人、爸爸、妈妈的编号
		vis[zd] = 1;
		if (fd != -1)
		{
			Merge(zd, fd);
			vis[fd] = 1;
		}
		if (md != -1)
		{
			Merge(zd, md);
			vis[md] = 1;
		}
		cin >> k;//孩子的数目
		for (int j = 0; j < k; j++)
		{
			cin >> cd;
			Merge(zd, cd), vis[cd] = 1;
		}
		cin >> a[zd].hnum >> a[zd].area;//房产套数和总面积
	}
	int top = 0;
	for (int i = 0; i < 10000; i++)//求家庭信息
	{
		if (vis[i])
		{
			int x = Find(i);
			if (vv[x])//领导者被初始化过的情况
			{
				for (int j = 0; j < top; j++)//遍历已有家庭
				{
					if (Find(ans[j].id) == x)//找到对应的家庭
					{
						ans[j].num++;
						ans[j].avearea += a[i].area;
						ans[j].avehnum += a[i].hnum;
						break;//找到就退出,减少时间复杂度
					}
				}
			}
			else//领导者没有初始化过的情况
			{
				vv[x] = 1;
				ans[top].id = i;//领导者编号
				ans[top].num = 1;
				ans[top].avearea = ans[top].avehnum = 0;
				ans[top].avearea += a[i].area;
				ans[top].avehnum += a[i].hnum;
				top++;
			}
		}
	}
	sort(ans, ans + top);//默认以结构体第一行排序,升序;
	//!!但是,由于上面的ans结构体对符号<进行了重载,所以排序结果由上面的函数决定
	cout << top << endl;
	for (int i = 0; i < top; i++)
	{
		/*cout << ans[i].id << " " << ans[i].num << " ";
		cout << fixed << setprecision(3) << (double)ans[i].avehnum / ans[i].num << " ";
		cout << fixed << setprecision(3) << (double)ans[i].avearea / ans[i].num << endl;*/
		printf("%.04d %d %.3lf %.3lf\n", ans[i].id, ans[i].num, 1.0*ans[i].avehnum / ans[i].num, 1.0*ans[i].avearea / ans[i].num);
	}
	system("pause");
	return 0;
}

附上printf()的格式输出

对于C语言的输出格式("/n%2d,%2.1f,%2.11f)是什么意思

#include "stdio.h" 
int main() 

int a=1234; 
float b=123.456;
double c=12345.54321;
printf("/n%2d,%2.1f,%2.11f",a,b,c);
}
输出结果为1234,123.5,12345.5


%md: m为指定输出数据的宽度 如果位数小于m,则左端补以空格,如果大于m,则按实际位数输出
             显然a=1234的位数是4 大于%2d中指定的长度2 按实践位数输出 所以结果为1234
%m.nf格式:指定输出数据宽度为m位,其中小数占n位,如果数值长度小于m,则左端补空格,%-m.nf与上差不多,只是如果               数值长度小于m,则右端补空格,大于的话就按原长度输出
%2.1f就是指长度2位,含一位小数位,由于原长度大于2,所以原样输出,但只能右一位小数,所以结果是123.4
%2.11f,就是含11位小数,显然长度不够,则右端补零 结果位12345.54321000000
 

请教%.2f与%1.2f有什么区别

1.2f是非法的,小数点前的数字必须大于小数点后的数字。小数点前的数值规定了打印的数字的总宽度。如果忽略了(也就是.2f),总宽度无限制。

%.lf(四舍五入)

C语言程序中浮点数类型(%.2lf)编译器默认四舍五入,(最好自行测试一遍,可能不同平台使用的C语言版本不同,语言标准也有细微的区别。)如果不需要四舍五入,则要自行处理(浮点数-5*10^(-x),x=需要保留的小数位+1)。(已经写过测试代码进行了验证!!!)。另外,float精度是2^23,能保证6位,double的精度是2^52,能保证15位。double精度的确有那么高,但是默认打印位数没有那么多。

%lf和%f那些事

1、%lf和%f 在scanf函数和printf函数看来是不一样的

     首先printf无论是%f还是%lf没有区别,因为当printf函数当遇到float类型时会自动转化为double,从c语言标准来说printf并没有%lf的定义,虽然大多数编译器都能接受,但在做题时printf最好用%f,否则可能出现一些莫名其妙的错误;

    对于scanf来说double就应该用%lf float就用%f

C语言中%d %.2d %2d %02d的区别

%d:即为普通的输出

%2d:按宽度为2输出,右对齐方式输出。若不够两位,左边补空格。

%02d:同样宽度为2,右对齐方式。位数不够,左边补0。

%.2d:从执行效果来看,与%02d一样。

求赞~~

猜你喜欢

转载自blog.csdn.net/weixin_43535668/article/details/104413573