[第六届蓝桥杯省赛C++B组]抽签

题目来源:第六届蓝桥杯省赛C++B组

算法标签:DFS

题目描述:

X星球要派出一个5人组成的观察团前往W星。

其中:

A国最多可以派出4人。

B国最多可以派出2人。

C国最多可以派出2人。


那么最终派往W星的观察团会有多少种国别的不同组合呢?
下面的程序解决了这个问题。

数组a[] 中既是每个国家可以派出的最多的名额。

程序执行结果为:

DEFFF

CEFFF

CDFFF

CDEFF

CCFFF

CCEFF

CCDFF

CCDEF

BEFFF

BDFFF

BDEFF

BCFFF

BCEFF

BCDFF

BCDEF

(以下省略,总共101行)

#include <stdio.h>
#define N 6
#define M 5
#define BUF 1024
 
void f(int a[], int k, int m, char b[])
{
	int i,j;
	
	if(k==N){ 
		b[M] = 0;
		if(m==0) printf("%s\n",b);
		return;
	}
	
	for(i=0; i<=a[k]; i++){
		for(j=0; j<i; j++) b[M-m+j] = k+'A';
		______________________;  //填空位置
	}
}
int main()
{	
	int  a[N] = {4,2,2,1,1,3};
	char b[BUF];
	f(a,0,M,b);
	return 0;
}

仔细阅读代码,填写划线部分缺少的内容。
注意:不要填写任何已有内容或说明性文字。

题目答案:

16

题目思路:

很明显的深搜,不难想到我们需要填的肯定就是递归语句,则现在我们的问题就转换为了弄懂参数起到什么作用。

f(int a[], int k, int m, char b[])

由题目可知一共有四个参数,其中a[N] = {4,2,2,1,1,3}printf("%s\n",b)表明了a用来存放国家,b用来表示字符串是显而易见的。
那我们现在的目标转换为了弄清看k,m的作用。

因为上文,我们弄清了a,b的作用。

for(i=0; i<=a[k]; i++){//a[k]当前国家最大派出人员数量
		for(j=0; j<i; j++) b[M-m+j] = k+'A';//字符串b拼接国家字符
		______________________;  //填空位置

我们可以明白k的作用即为表达当前选择国家的下标。
现在我们的目标转向弄清m的意思。
阅读b[M-m+j] = k+'A'可以勉强清晰,这里的意思大概是给字符串b赋予国别字符,其中M是队伍人员总数,j是国家派出的人数,所以m大致起到也起到了计数的作用。

阅读退出条件

	if(k==N){ //所有国家计数完毕
		b[M] = 0;
		if(m==0) printf("%s\n",b);//如果m==0则输出字符串
		return;

且一开始递归时f(a,0,M,b); m的位置传的参数即为M队伍最大人数,不难想出,m表明的是队伍剩余位子,当所有国家计数完毕且队伍剩余位子为0时输出答案。

则综上我们不难给出答案。

f(a,k+1,m-i,b)

或者

f(a,k+1,m-j,b)

注意

1.a,b作为数组不做变更只做传入。
2.k+1表明递归到下一个国家选择
3.m-i或者m-j表明队伍空位减去一个国家派出的人数
4.i,j的范围实际相同,没有区别。

发布了155 篇原创文章 · 获赞 18 · 访问量 3911

猜你喜欢

转载自blog.csdn.net/weixin_43910320/article/details/105142656