2024-03-01
数据结构与算法
00
请注意,本文编写于 447 天前,最后修改于 396 天前,其中某些信息可能已经过时。

大一新生,刚看题目觉得不难,试图暴力枚举,结果失败,遂放弃,打完后才反应过来是搜索,于是又重写了一遍,记于此提醒自己。

分析题目,这就是个3种不同的小球不重复排列组合的题,于是我简化了一下,让k为1,d为2,a为3开始排列组合,每组合出一种结果判断是否25层,最后输出所有符合的个数,简简单单。

最开始套了个模板,结果超时了一点

cpp
#include<iostream> using namespace std; #define kk 5 #define dd -10 #define aa 2 int b[21]= {0},sum=0,book[4]= {0},sumn=0; //初始化数据数组,标记数组,总层数,满足的情况总数,一定是全局变量,因为每层递归需要用上一次的结果 int k,d,a,n; //算法核心,一个简单的深度搜索 void dfs(int s) { if(s==n+1) { //如果到结尾了,判断层数是否等于25 sum=0; for(int i=1;i<=n;i++){ if(b[i]==1) sum+=kk; //计算层数 if(b[i]==2) sum+=dd; if(b[i]==3) sum+=aa; if(sum<0) sum=0; //低于0层也是0层 if(sum>25) sum=25; //高于25层也是25层 } if(sum==25) sumn++; //如果层数满足,总数加一 return; } //每一位开始递归 for(int j=1; j<=3; j++) { if(book[j]) { //如果还有此种数据就把它扔一个进数组去 b[s]=j; book[j]--; //该种数据个数减一 dfs(s+1); //递归判断下一位 book[j]++; //再倒着把这种数据捡回来 } } return; } //主函数 int main() { cin>>k>>d>>a; n=k+d+a; book[1]=k; //初始化标记数组,存储k,d,a的个数 book[2]=d; book[3]=a; dfs(1); //从第一位开始递归 cout<<sumn; return 0; }

我一看,这个判断层数没必要等组合出来再从头算啊,如果前面的都一样,最后两位不一样,那岂不是浪费功夫,于是我就把判断也加到了递归里

cpp
#include<iostream> using namespace std; int b[21]= {0},sum=0,book[4]= {0},sumn=0,bj[4]= {0,5,-10,2}; int k,d,a,n; //简化过程 void dfs(int s) { int t; //一个中间变量t,存储新加一个数据之前的总层数,不能是全局变量,只让它在本层递归起作用 if(s==n+1) { //同样的,到了总长度时就判断层数 if(sum==25) sumn++; return; } for(int j=1; j<=3; j++) { if(book[j]) { b[s]=j; book[j]--; t=sum; //存储之前的层数 sum+=bj[j]; //新的数据改变层数 if(sum<0) sum=0; //一样的让它处于0到25 if(sum>25) sum=25; dfs(s+1); //递归下一位 book[j]++; //还回来一个数据 sum=t; //总层数也还原 } } return; } //主函数 int main() { cin>>k>>d>>a; n=k+d+a; book[1]=k; book[2]=d; book[3]=a; dfs(1); cout<<sumn; return 0; }

果然,快了一倍还多,可以打出GG了。

本文作者:KID

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!