这个题一共有两种方法,一个是暴力枚举法,另一个是简单的递归法
这个问题可拆解为总共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;
}
运行结果如图所示:
本以为这题这么快就做完了,没想到提交上去说答案错了
好吧,那重新调试一下,重理一下思路
从我的终端结果显示,经过手动验证,发现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;
}
这次运行出的结果是
85 > 72,显然我这里又有问题了,然后进行第二次查找错误修改代码
这两个地方刚好就是多出来的13个方案,接下来进一步修改代码
通过调试,找到问题所在
#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;
}