每日编程中遇到任何疑问、意见、建议请公众号留言或加入每日编程群聊739635399
有一个研究团队,团队分成许多研究小组,每个小组的一部分成员可能再分成小组。小组的成员只知道自己的组长是谁,而在同一个组长领导下的成员之间却相互不认识。现在这个团队希望有一个程序能统计一下各组长带领小组的规模,即对每一个成员想知道自己及自己带领下的小组有多少人。
输入格式:
2行,第1行有1个数字N(0<N<2×105)(0<N<2×105),代表小组的人数
第2行有N个数a1,a2,...,ai,...,aN,表示第i个人的领导是ai。团队的领导用0表示,说明没有人做他的组长。数据保证没有环路。单独的一个成员视为1个人的小组。
输出格式:
1行,N个数字,表示第i名成员的团队的规模输入样例:
6
0 1 2 1 2 2
输出样例:
6 4 1 1 1 1
解决方法:
(1)算法的基本思想:
画出下图所示的双亲表示法的树:
根据其数组给出的方式,当求以1为根节点的所包含的结点的个数时,3->2->1, 5->2->1,
6->2->1, 2->1, 4->1共有5+1=6个,同理可得2是3+1=4个。可以定义一个数组,遍历这个双亲表示法的数组,看每个节点被扫描的次数即是以其为根节点所包含的结点的数目。
(2)代码实现:
#include <iostream>
using namespace std;
void manageNum(int *arr, int n)
{
//创建一个计数的数组
int *b = new int[n + 1];
//数组初始化
for (int i = 1; i <= n + 1; i++)
b[i] = 1;
for (int i = 1; i < n + 1; i++)
{
if (arr[i] == 0)
continue;
else
{
int k = i;
while (arr[k] != 0)
{
int j = arr[k];
b[j]++;
k = j;
}
}
}
for (int i = 1; i < n + 1; i++)
cout << b[i] << " ";
}
int main()
{
cout << "输入团队的总人数:";
int n = 0;
cin >> n;
int *arr = new int[n + 1];
//双亲表示法数组的输入
for (int i = 1; i < n + 1; i++)
cin >> arr[i];
manageNum(arr, n);
system("pause");
return 0;
}
假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队。跳舞开始时,依次从男队和女队的队头上各出一人配成舞伴。规定每个舞曲能有一对跳舞者。若两队初始人数不相同,则较长的那一队中未配对者等待下一轮舞曲。现要求写一个程序,模拟上述舞伴配对问题。
输入格式:
三个整数m , n, k ( 1≤m,n≤150,1≤k≤4000 ),分别表示男士人数、女士人数、几轮舞曲。输出格式:
输出各轮舞曲的配对方案。
输入样例:
2 4 6
输出样例:
1 1
2 2
1 3
2 4
1 1
2 2