您的位置:首页 > 编程语言 > C语言/C++

蓝桥杯——派遣敢死队问题—C语言

2016-03-19 16:04 489 查看
蓝桥杯比赛题目:

题目描述:

G将军有一支训练有素的军队,这个军队除开G将军外,每名士兵都有一个直接上级(可能是其他士兵,也可能是G将军)。现在G将军将接受一个特别的任务,需要派遣一部分士兵(至少一个)组成一个敢死队,为了增加敢死队队员的独立性,要求如果一名士兵在敢死队中,他的直接上级不能在敢死队中。

请问,G将军有多少种派出敢死队的方法。注意,G将军也可以作为一个士兵进入敢死队。

输入格式

输入的第一行包含一个整数n,表示包括G将军在内的军队的人数。军队的士兵从1至n编号,G将军编号为1。

接下来n-1个数,分别表示编号为2, 3, ..., n的士兵的直接上级编号,编号i的士兵的直接上级的编号小于i。

输出格式

输出一个整数,表示派出敢死队的方案数。由于数目可能很大,你只需要输出这个数除10007的余数即可。

样例输入1

3

1 1

样例输出1

4

样例说明

这四种方式分别是:

1. 选1;

2. 选2;

3. 选3;

4. 选2, 3。

样例输入2

7

1 1 2 2 3 3

样例输出2

40

数据规模与约定

对于20%的数据,n ≤ 20;

对于40%的数据,n ≤ 100;

对于100%的数据,1 ≤ n ≤ 100000。

资源约定:

峰值内存消耗 < 256M

CPU消耗 < 2000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0

注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。

注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

解题思想:

求出所有的组合数,然后进行判断是否满足条件,,来看代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<conio.h>
bool judge(long c[],long m);
int combine(long a[],long n,long m,long c[],const long M);
long a[100001];//储存士兵编号
long b[100001];//储存其领导编号
long c[100001];//储存组合
long long count=0;
int main()
{
long n,i;
scanf("%d",&n);
b[1]=0;//G将军没领导,令其领导为0
for(i=2;i<=n;i++)
scanf("%d",&b[i]);
for(i=1;i<=n;i++)
a[i]=i;
for(i=1;i<=n;i++)
combine(a,n,i,c,i);//从n个人中选出i个人
printf("%lld",count);
return 0;
}

int combine(long a[],long n,long m,long c[],const long M)//计算所有的组合
{
for(long i=n;i>=m;i--)
{
c[m]=i;
if(m>1)
{
combine(a,i-1,m-1,c,M);
}
else
{
if(judge(c,M))	 	count++;
count%=10007;
}

}
}

bool judge(long c[],long m)//判断其中是否有其上级
{
long i,j;
for(i=1;i<=m;i++)
{
for(j=1;j<=m;j++)
if(b[c[i]]==c[j])   return false;
}
return true;
}


其中涉及组合数的求解,,请看我的另一篇对组合数的介绍:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: