2020 计蒜客蓝桥杯省赛 B 组模拟赛(一)题解2.爬楼梯

每日刷题(六)

爬楼梯(结果填空题)

2020 计蒜客蓝桥杯省赛 B 组模拟赛(一)题解2.爬楼梯_第1张图片
这个题一共有两种方法,一个是暴力枚举法,另一个是简单的递归法

方法一、暴力枚举法

这个问题可拆解为总共10层台阶,每次上台阶的高度为1~4台阶的范围,不能上第五第七层楼梯,求上楼梯总共的方案。
这里我设了一些变量,sum记录走过的台阶数,num表示方案数,s表示第一次跨越,a表示第二次跨越,b表示第三次跨越,c表示第四次跨越,d表示第五次跨越,e表示第六次跨越,f表示第七次跨越,g表示第八次跨越
C语言代码如下:

#include

int main()
{
	int s, a, b, c, d, e, f, g, sum, num = 0, flag = 0;  //sum记录走过的台阶数,num表示方案数 
/*  s表示第一次跨越,a表示第二次跨越,b表示第三次跨越,c表示第四次跨越,
    d表示第五次跨越,e表示第六次跨越,f表示第七次跨越,g表示第八次跨越 
*/
	for(s = 1; s <= 4; s++)			//第一次 
	{
		sum = 0;
		sum += s;
		for(a = 1; a <= 4; a++)			//第二次 
		{
			sum += a;
			if(sum == 5)			//第五台阶不能踩 
			{
				sum -= a; 
				continue;
			}
			if(sum == 7)
			{
				sum -= a; 
				continue;
			}
			/*第一二次不用激活*/
			for(b = 1; b <= 4; b++)			//第三次 
			{
				if(flag)
				{
					sum -= c + b - 1;
				}				
				flag = 0;		//使用完后立即失效				 
				if(b > 4)
					break;
				sum += b;
				if(sum == 5)
				{
					sum -= b; 
					continue;
				}
				if(sum == 7)
				{
					sum -= b; 
					continue;
				}
				if(sum == 10)
				{
					num ++;
					printf("Project %5d : %d %d %d \n",num, s, a, b);
				} 
				if(sum > 10) 
					break;
				for(c = 1; c <= 4; c++)
				{
					if(flag)
					{
						sum -= d + c - 1;
					}			
					flag = 0;		//使用完后立即失效					 
					if(c > 4)
						break;
					sum += c;
					if(sum == 5)
					{
						sum -= c; 
						continue;
					}
					if(sum == 7)
					{
						sum -= c; 
						continue;
					}
					if(sum == 10)
					{
						num ++;
						printf("Project %5d : %d %d %d %d \n",num, s, a, b, c);
						flag = 1;
						break;
					} 
					if(sum > 10) 
						break;
					for(d = 1; d <= 4; d++)
					{
						if(flag)
						{
							sum -= e + d - 1;
						}				
						flag = 0;		//使用完后立即失效				 
						if(d > 4)
							break;
						sum += d;
						if(sum == 5)
						{
							sum -= d; 
							continue;
						}
						if(sum == 7)
						{
							sum -= d; 
							continue;
						}
						if(sum == 10)
						{
							num ++;
							printf("Project %5d : %d %d %d %d %d \n",num, s, a, b, c, d);							
							flag = 1;
							break;
						} 
						if(sum > 10) 
							break;
						for(e = 1; e <= 4; e++)
						{
							if(flag)
							{
								sum -= f + e - 1;
							}		
							flag = 0;		//使用完后立即失效						 
							if(e > 4)
								break;
							sum += e;
							if(sum == 5)
							{
								sum -= e; 
								continue;
							}
							if(sum == 7)
							{
								sum -= e; 
								continue;
							}
							if(sum == 10)
							{
								num ++;
								printf("Project %5d : %d %d %d %d %d %d \n",num, s, a, b, c, d, e);						
								flag = 1;
								
								break;
							} 
							if(sum > 10) 
								break;
							for(f = 1; f <= 4; f++)
							{
								if(flag)
								{
									sum -= g + f - 1;
								}		
								flag = 0;		//使用完后立即失效						 
								if(f > 4)
									break;
								sum += f;
								if(sum == 5)
								{
									sum -= f; 
									continue;
								}
								if(sum == 7)
								{
									sum -= f; 
									continue;
								}
								if(sum == 10)
								{
									num ++;
									printf("Project %5d : %d %d %d %d %d %d %d \n",num, s, a, b, c, d, e, f);
									flag = 1;			//激活回返 
									break;
								} 
								if(sum > 10) 
									break;
								for(g = 1; g <= 4; g++)
								{
									sum += g;
									if(sum == 5)
									{
										sum -= g; 
										continue;
									}
									if(sum == 7)
									{
										sum -= g; 
										continue;
									}
									if(sum == 10)
									{
										num ++;
										printf("Project %5d : %d %d %d %d %d %d %d %d \n",num, s, a, b, c, d, e, f, g);
										flag = 1;			//激活回返 
										break;
									} 
									if(sum > 10) 
										break;
								}
							}
						}
					} 
				}
			}
		}
	}
	return 0;
}

运行结果如图所示:
2020 计蒜客蓝桥杯省赛 B 组模拟赛(一)题解2.爬楼梯_第2张图片
本以为这题这么快就做完了,没想到提交上去说答案错了
2020 计蒜客蓝桥杯省赛 B 组模拟赛(一)题解2.爬楼梯_第3张图片
好吧,那重新调试一下,重理一下思路
从我的终端结果显示,经过手动验证,发现Project 7出现了问题 1 1 1 2 2 1 1,这款方案都不满足题意,踩过了第五层和第七层台阶,debug之后发现在project 6的基础上sum少减去了4,因为f = 5直接跳过了循环也跳过了sum的处理
所以我再次修改了以下代码,如下

#include

int main()
{
	int s, a, b, c, d, e, f, g, sum, num = 0, flag = 0;  //sum记录走过的台阶数,num表示方案数 
/*  s表示第一次跨越,a表示第二次跨越,b表示第三次跨越,c表示第四次跨越,
    d表示第五次跨越,e表示第六次跨越,f表示第七次跨越,g表示第八次跨越 
*/
	for(s = 1; s <= 4; s++)			//第一次 
	{
		sum = 0;
		sum += s;
		for(a = 1; a <= 4; a++)			//第二次 
		{
			sum += a;
			if(sum == 5)			//第五台阶不能踩 
			{
				sum -= a; 
				continue;
			}
			if(sum == 7)
			{
				sum -= a; 
				continue;
			}
			/*第一二次不用激活*/
			for(b = 1; b <= 4; b++)			//第三次 
			{
				if(flag)
				{
					sum = 0;
					sum += a + s;
				}				
				flag = 0;		//使用完后立即失效				 
				if(b > 4)
					break;
				sum += b;
				if(sum == 5)
				{
					sum -= b; 
					continue;
				}
				if(sum == 7)
				{
					sum -= b; 
					continue;
				}
				if(sum == 10)
				{
					num ++;
					printf("Project %5d : %d %d %d \n",num, s, a, b);
				} 
				if(sum > 10) 
					break;
				for(c = 1; c <= 4; c++)
				{
					if(flag)
					{
						sum = 0;
						sum += a + b + s;
					}			
					flag = 0;		//使用完后立即失效					 
					if(c > 4)
						break;
					sum += c;
					if(sum == 5)
					{
						sum -= c; 
						continue;
					}
					if(sum == 7)
					{
						sum -= c; 
						continue;
					}
					if(sum == 10)
					{
						num ++;
						printf("Project %5d : %d %d %d %d \n",num, s, a, b, c);
						flag = 1;
						break;
					} 
					if(sum > 10) 
						break;
					for(d = 1; d <= 4; d++)
					{
						if(flag)
						{
							sum = 0;
							sum += a + b + s + c;
						}				
						flag = 0;		//使用完后立即失效				 
						if(d > 4)
							break;
						sum += d;
						if(sum == 5)
						{
							sum -= d; 
							continue;
						}
						if(sum == 7)
						{
							sum -= d; 
							continue;
						}
						if(sum == 10)
						{
							num ++;
							printf("Project %5d : %d %d %d %d %d \n",num, s, a, b, c, d);							
							flag = 1;
							break;
						} 
						if(sum > 10) 
							break;
						for(e = 1; e <= 4; e++)
						{
							if(flag)
							{
								sum = 0;
								sum += a + b + s + c + d;
							}		
							flag = 0;		//使用完后立即失效						 
							if(e > 4)
								break;
							sum += e;
							if(sum == 5)
							{
								sum -= e; 
								continue;
							}
							if(sum == 7)
							{
								sum -= e; 
								continue;
							}
							if(sum == 10)
							{
								num ++;
								printf("Project %5d : %d %d %d %d %d %d \n",num, s, a, b, c, d, e);						
								flag = 1;
								
								break;
							} 
							if(sum > 10) 
								break;
							for(f = 1; f <= 4; f++)
							{
								if(flag)
								{
									sum = 0;
									sum += a + b + s + c + d + e;
								}		
								flag = 0;		//使用完后立即失效						 
								if(f > 4)
									break;
								sum += f;
								if(sum == 5)
								{
									sum -= f; 
									continue;
								}
								if(sum == 7)
								{
									sum -= f; 
									continue;
								}
								if(sum == 10)
								{
									num ++;
									printf("Project %5d : %d %d %d %d %d %d %d \n",num, s, a, b, c, d, e, f);
									flag = 1;			//激活回返 
									break;
								} 
								if(sum > 10) 
									break;
								for(g = 1; g <= 4; g++)
								{
									sum += g;
									if(sum == 5)
									{
										sum -= g; 
										continue;
									}
									if(sum == 7)
									{
										sum -= g; 
										continue;
									}
									if(sum == 10)
									{
										num ++;
										printf("Project %5d : %d %d %d %d %d %d %d %d \n",num, s, a, b, c, d, e, f, g);
										flag = 1;			//激活回返 
										break;
									} 
									if(sum > 10) 
										break;
								}
							}
						}
					} 
				}
			}
		}
	}
	return 0;
}

这次运行出的结果是
2020 计蒜客蓝桥杯省赛 B 组模拟赛(一)题解2.爬楼梯_第4张图片
85 > 72,显然我这里又有问题了,然后进行第二次查找错误修改代码
2020 计蒜客蓝桥杯省赛 B 组模拟赛(一)题解2.爬楼梯_第5张图片
这两个地方刚好就是多出来的13个方案,接下来进一步修改代码
通过调试,找到问题所在

2020 计蒜客蓝桥杯省赛 B 组模拟赛(一)题解2.爬楼梯_第6张图片
经过我的反复调试终于出正确结果了
2020 计蒜客蓝桥杯省赛 B 组模拟赛(一)题解2.爬楼梯_第7张图片
详细C语言代码如下:

#include

int main()
{
	int s, a, b, c, d, e, f, g, sum, num = 0, flag = 0;  //sum记录走过的台阶数,num表示方案数 
/*  s表示第一次跨越,a表示第二次跨越,b表示第三次跨越,c表示第四次跨越,
    d表示第五次跨越,e表示第六次跨越,f表示第七次跨越,g表示第八次跨越 
*/
	for(s = 1; s <= 4; s++)			//第一次 
	{
		sum = 0;
		sum += s;
		for(a = 1; a <= 4; a++)			//第二次 
		{
			if(b == 5)
			{
				sum = 0;
				sum += s;
			}
			sum += a;
			if(sum == 5)			//第五台阶不能踩 
			{
				sum -= a; 
				continue;
			}
			if(sum == 7)
			{
				sum -= a; 
				continue;
			}
			/*第一二次不用激活*/
			for(b = 1; b <= 4; b++)			//第三次 
			{
				if(flag)
				{
					sum = 0;
					sum += a + s;
				}				
				flag = 0;		//使用完后立即失效				 
				if(b > 4)
					break;
				sum += b;
				if(sum == 5)
				{
					sum -= b; 
					continue;
				}
				if(sum == 7)
				{
					sum -= b; 
					continue;
				}
				if(sum == 10)
				{
					num ++;
					printf("Project %5d : %d %d %d \n",num, s, a, b);
				} 
				if(sum > 10) 
					break;
				for(c = 1; c <= 4; c++)
				{
					if(flag)
					{
						sum = 0;
						sum += a + b + s;
					}			
					flag = 0;		//使用完后立即失效					 
					if(c > 4)
						break;
					sum += c;
					if(sum == 5)
					{
						sum -= c; 
						continue;
					}
					if(sum == 7)
					{
						sum -= c; 
						continue;
					}
					if(sum == 10)
					{
						num ++;
						printf("Project %5d : %d %d %d %d \n",num, s, a, b, c);
						flag = 1;
						break;
					} 
					if(sum > 10) 
						break;
					for(d = 1; d <= 4; d++)
					{
						if(flag)
						{
							sum = 0;
							sum += a + b + s + c;
						}				
						flag = 0;		//使用完后立即失效				 
						if(d > 4)
							break;
						sum += d;
						if(sum == 5)
						{
							sum -= d; 
							continue;
						}
						if(sum == 7)
						{
							sum -= d; 
							continue;
						}
						if(sum == 10)
						{
							num ++;
							printf("Project %5d : %d %d %d %d %d \n",num, s, a, b, c, d);							
							flag = 1;
							break;
						} 
						if(sum > 10) 
							break;
						for(e = 1; e <= 4; e++)
						{
							if(flag)
							{
								sum = 0;
								sum += a + b + s + c + d;
							}		
							flag = 0;		//使用完后立即失效						 
							if(e > 4)
								break;
							sum += e;
							if(sum == 5)
							{
								sum -= e; 
								continue;
							}
							if(sum == 7)
							{
								sum -= e; 
								continue;
							}
							if(sum == 10)
							{
								num ++;
								printf("Project %5d : %d %d %d %d %d %d \n",num, s, a, b, c, d, e);						
								flag = 1;
								
								break;
							} 
							if(sum > 10) 
								break;
							for(f = 1; f <= 4; f++)
							{
								if(flag)
								{
									sum = 0;
									sum += a + b + s + c + d + e;
								}		
								flag = 0;		//使用完后立即失效						 
								if(f > 4)
									break;
								sum += f;
								if(sum == 5)
								{
									sum -= f; 
									continue;
								}
								if(sum == 7)
								{
									sum -= f; 
									continue;
								}
								if(sum == 10)
								{
									num ++;
									printf("Project %5d : %d %d %d %d %d %d %d \n",num, s, a, b, c, d, e, f);
									flag = 1;			//激活回返 
									break;
								} 
								if(sum > 10) 
									break;
								for(g = 1; g <= 4; g++)
								{
									sum += g;
									if(sum == 5)
									{
										sum -= g; 
										continue;
									}
									if(sum == 7)
									{
										sum -= g; 
										continue;
									}
									if(sum == 10)
									{
										num ++;
										printf("Project %5d : %d %d %d %d %d %d %d %d \n",num, s, a, b, c, d, e, f, g);
										flag = 1;			//激活回返 
										break;
									} 
									if(sum > 10) 
										break;
								}
							}
						}
					} 
				}
			}
		}
	}
	return 0;
}

方法二、递归法

#include

int stairs(int k)		 
{
	if(k == 0)
		return 1;
	if(k < 0)
		return 0;
	if(k == 5 || k == 7)
		return 0;
	else
	{
		return stairs(k - 1) + stairs(k - 2) + stairs(k - 3) + stairs(k - 4);
	}
} 

int main()
{
	int N;
	scanf("%d",&N);
	printf("%d\n",stairs(N));
	return 0;
}

在这里插入图片描述

这道题目的讲解到这里也就结束了,如果对递归算法不是很熟练的朋友,可以点击这篇文章——算法一:递归

如果喜欢我的文章,请记得三连哦,点赞关注收藏,感谢支持,下期更精彩!!!

你可能感兴趣的:(2020,蓝桥杯省赛,B,组模拟赛(一)题解)