蓝桥杯训练中的考新郎问题

题目内容:

国庆期间,省城HZ刚刚举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,

叫做"考新郎",具体的操作是这样的:首先,给每位新娘打扮得几乎一模一样,并盖上大大的红盖头随机坐成一排;然后,

让各位新郎寻找自己的新娘.每人只准找一个,并且不允许多人找一个.最后,揭开盖头,如果找错了对象就要当众跪搓

衣板.. 假设一共有N对新婚夫妇,其中有M个新郎找错了新娘,求发生这种情况一共有多少种可能.

输入描述

N M

输出描述

可能的种数

输入样例

3 2

输出样例

3

/*分析:就是计算数学里面的组合数*/

/*再分析:这才发现自己之前都弄错了,根本不是什么组合数,但是跟组合数有关,是错排,不过跟一般错排有一点差

别,就是不是对所有的元素进行错排,只是对部分进行错排,说道对部分进行错排,那就与组合数有关系了啊,因此先

解决组合数的求法然后乘以错排数就是结果了。

先来实现组合数求解

C(n,m)=(n*(n-1)*(n-2)*…*(n-m+2)*(n-m+1))/(m!)=((n-m+1)/1)*((n-m+2)/2)*((n-m+3)/3)*…*((n-m+m)/n)

=∏((n-m+k)/k)【k=1,2,3,…,m】

以上变换是把一般数学计算中的求组合数的步骤进行变换,变化方便计算机求解的方式

*/

下面是求组合数的代码:

#include<stdio.h>

int Combination(int n,int m)
{
	int i;
	int sum = 1;//这里sum在之后的算式中是以乘数的形式出现的,所以不能是0,应该设置初值为1
	for(i = 1;i <= m; i++)
		sum = (sum * (n - m + i))/i;
	return sum;
}

int main()
{
	int n,m;
	int count = 0;
	scanf("%d%d",&n,&m);
	count = Combination(n,m);
	printf("%d\n",count);
	return 0;
}

分析:好的,现在把求组合的方法搞定了,那么接下来就是就有条件的错排了,a[i]=(i-1)*(a[i-1]+a[i-2])(a[0] = 0,a[1] = 0,a[2] = 1),在网上找到了错排的公式,剩下的就好做了

#include<stdio.h>
#define M 200
double sum = 1;

double Combination(int p,int q)
{
	int i;
	//double sum = 1;/*这里sum在之后的算式中是以乘数的形式出现的,所以不能是0,应该设置初值为1*/
	for(i = 1;i <= q; i++)
		sum = (sum * (p - q + i))/i;
	return sum;
}

int main()
{
	int n,m;
	int j;
	double co = 1;
	double array[M] = {0,0,1};
	double out = 1;
	scanf("%d%d",&n,&m);
	out = Combination(n,n - m);
	/*for(j = 0;j < 10; j++)
		printf("%.0lf ",array[j]);
	printf("\n");*/
	for(j = 3;j <= M;j++)
	{
		array[j] =((double)(j - 1)) * (array[j - 1] + array[j - 2]);
		//printf("j = %d\n",j);
	}
	/*for(j = 0;j < 10; j++)
		printf("%.0lf ",array[j]);
	printf("\n");*/
	//printf("ar[2] = %.0f\n",array[2]);
	out = array[m]*out;
	printf("%.0lf",out);
	return 0;
}

赶快编译链接,都ok~~,那就没有问题了~~,果然,输入题目的数据,ok了。。so easy 是不是啊?!

只好检查错误,接下来是见证奇迹的时刻,当我把double co = 1;这句话给注释掉后,然后编译链接,最后运行,貌似都可以,但是在我输入数据后,一个回车,程序却没有了结果(可爱的是电脑的风扇却像嘲笑我似得开始努力工作起来了)。傻眼了~~~为什么啊,明明它是个无关的变量,去掉应该无所谓啊~~然后我开始了各种折腾,改double,改变量的名字...都不行,奇了怪了...想到刚才程序没有结果时电脑风扇就努力扇风的状况,我猜是有什么死循环之类的,于是就在主程序的for循环里面加了个输出,果然,是个死循环,终止条件没有起作用,看来问题在循环里面,但是为什么每次循环到200后又会重新开始循环呢?看来应该是终止条件有问题,我的终止条件是j
<= M。M宏定义为200。感觉没有问题啊。于是各种试,最后,我去掉了j <= M中的等号,然后,然后,然后它就好了...虽然不知道是什么原因,自己下次注意这个问题就好了。

总结:for循环中终止条件不能为i <= M,只能为i < M

时间: 2024-12-21 11:56:43

蓝桥杯训练中的考新郎问题的相关文章

蓝桥杯训练 安慰奶牛 (Kruskal MST)

算法训练 安慰奶牛 时间限制:1.0s   内存限制:256.0MB 问题描述 Farmer John变得非常懒,他不想再继续维护供奶牛之间供通行的道路.道路被用来连接N个牧场,牧场被连续地编号为1到N.每一个牧场都是一个奶牛的家.FJ计划除去P条道路中尽可能多的道路,但是还要保持牧场之间 的连通性.你首先要决定那些道路是需要保留的N-1条道路.第j条双向道路连接了牧场Sj和Ej(1 <= Sj <= N; 1 <= Ej <= N; Sj != Ej),而且走完它需要Lj的时间.

蓝桥杯训练 字串统计 (暴力+substr)

算法训练 字串统计 时间限制:1.0s   内存限制:512.0MB 问题描述 给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然有多个,输出第一次出现最早的. 输入格式 第一行一个数字L. 第二行是字符串S. L大于0,且不超过S的长度. 输出格式 一行,题目要求的字符串. 输入样例1: 4 bbaabbaaaaa 输出样例1: bbaa 输入样例2: 2 bbaabbaaaaa 输出样例2: aa 数据规

蓝桥杯 六角形中填置1~12个数字 dfs

如图[1.png]所示六角形中,填入1~12的数字. 使得每条直线上的数字之和都相同. 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少? 请通过浏览器提交答案,不要填写多余的内容. /**将12个数字放置到12个位置中,深度搜索,暴力枚举的方法*每放置一个数字,检查之前所放置位置的数字是否出现重复*当恰好放置12个数字并且六个边的和相同打印出所有的数字 */#include<stdio.h>#include<string.h>int t[6];int num[12

蓝桥杯训练之ACM

题目内容: 现有长度为n 的字符串,该字符串只由"A","C","M"三种字符组成(可以只有其中一种或两种字符, 但绝对不能有其他字符 ),但是禁止在串中出现C 相邻的情况,求一共有多少种满足要求的不同的字符串. 例如:n=2 时,有AA,AC,AM,CA,CM,MA,MC,MM 8 种情况. 输入描述 长度整数n(n<40) 输出描述 字符串的种数 输入样例 2 输出样例 8 #include<stdio.h> #includ

蓝桥杯训练 最短路 (SPFA模板 vector)

算法训练 最短路 时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环).请你计算从1号点到其他点的最短路(顶点从1到n编号). 输入格式 第一行两个整数n, m. 接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边. 输出格式 共n-1行,第i行表示1号点到i+1号点的最短路. 样例输入 3 3 1 2 -1 2 3 -1 3 1 2 样例输出 -1 -2 数据规模与约定 对于10%的数据,n

蓝桥杯训练 2n皇后

问题描述 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行.同一列或同一条对角线上,任意的两个白皇后都不在同一行.同一列或同一条对角线上.问总共有多少种放法?n小于等于8.输入格式 输入的第一行为一个整数n,表示棋盘的大小. 接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后.输出格式 输出一个整数,表示总共有多少种放法.样例输入41 1 1 11 1

日期类的使用(java)-蓝桥杯

蓝桥杯日期问题常考,java提供了日期类很方便: //日历类 Calendar c = Calendar.getInstance(); // 获取实例化对象 Date date =c.getTime();      // 日期类得到c的时间: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss"); // 修改格式 SimpleDateFormat sdf2 = new SimpleDateFormat(&q

蓝桥杯——算法训练之乘积最大

问题描述 今年是国际数学联盟确定的"2000--世界数学年",又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加.活动中,主持人给所有参加活动的选手出了这样一道题目: 设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大. 同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子: 有一个数字串:312, 当N=3,K=1时

蓝桥杯——真题训练之蚂蚁感冒

标题:蚂蚁感冒 长100厘米的细长直杆子上有n只蚂蚁.它们的头有的朝左,有的朝右. 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒. 当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行. 这些蚂蚁中,有1只蚂蚁感冒了.并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁. 请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒. [数据格式] 第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数. 接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100),