算法起步(3)抽签问题—合二为一(上)
来源:互联网 发布:apache用户访问认证 编辑:程序博客网 时间:2024/04/29 07:50
抽签问题(C++)—合二为一(上)
你的朋友提议玩一个游戏:把写有数字的n个纸片放入一个袋子里,
你可以从中抽取4张纸片,每次抽取后把纸片放回到袋子里,如果
抽取的4张纸片上的数字和为m,就算你赢,否则你输,抽了很多
次,结果你完败,那么我可以胜利吗?假设纸牌上的数字依次为k1,
k2,k3,k4,….ki,试写一个程序判断你是否有胜利的可能
限制条件:
n(1,50)
m(1,10^8)
ki(1,10^8)
const int MAX_N = 50;int main(){ //是否查找到符合条件的组合的标志 bool f=false; int n,m; int k[MAX_N]; //从标准输入输入 scanf("%d %d",&n,&m); for(i = 0;i<n;i++){ scanf("%d",&k[i]);} for(int a = 0;a<n;a++){ for(int b = 0;b<n;b++){ for(int c = 0;c<n;c++){ for(int d = 0;d<n;d++){ if(m==k[a]+k[b]+k[c]+k[d]) f=true;}}}} //从标准输出输出 if(f) //printf("%d/n",yes); puts("Yes"); else{ //printf("%d/n",no); puts("no");}}
是否觉得超级简单,那么问题来了,当n = 1000时,我们的算法复杂度1000^3,我们需要降低其复杂度
如何去做,如何结合二分法降低其复杂度
二分法:将数据从小到大排列,取中间数,如果比中间数大,在后半部分查找,如果比中间数小,在前半部分查找
int n,m; int k[MAX_N]; bool f = false; bool binary_search(int x) //k[l],k[l+1],k[l+2]....k[r-1] { while(r-1>1){ int l=0; int r=n; int i=(l+r)/2; if(x>k[i]) l=i+1; else if(x==k[i]) return true; else r=i; } return false; } void solve(){ sort(k,k+n); for(a = 0;a<n;a++){ for(b = 0;b<n;b++){ for(c = 0;c<n;c++){ if(binary_search(m-k[a]-k[b]-k[c])){ f = true;}}}} if(f) puts("Yes"); else puts("no");}
第一次优化算法后,让我们来看看复杂度排序nlogn循环n^3lognn^3logn比nlogn大,所以复杂度为n^3logn
0 0
- 算法起步(3)抽签问题—合二为一(上)
- 算法起步(3)抽签问题—合二为一(下)
- 抽签问题改进算法
- 白书1.6.3 抽签问题(第一个搜索代码...)
- 算法起步(1)
- 算法起步(2)
- 抽签(蓝桥杯)
- 抽签(蓝桥杯)
- 算法小题之抽签问题
- 暴力枚举算法的优化:抽签问题
- 增加难度的抽签问题(最内层使用二分法)
- 增加难度的抽签问题(最内两层使用二分法)
- 熊猫阿波的故事(无顺序抽签问题)
- 抽签问题
- 抽签问题
- 抽签问题
- 抽签问题
- 抽签问题
- 机器学习实战-第三章决策树-代码理解-读书笔记
- Android中的Service 与 Thread 的区别
- 【hdu2298】Toxophily——三分+二分
- Unix下C程序内存泄漏检测工具Valgrind安装与使用
- 找不到ServiceRegistryBuilder()函数的解决方法
- 算法起步(3)抽签问题—合二为一(上)
- 获取用户登录的设备类型 系统+版本号
- CABasicAnimation的简单使用
- Codis 的设计与实现 Part 2
- mysql create trigger and procedure demo
- Codis 的设计与实现 Part 3
- 使用PowerDesigner进行面向对象分析与UML建模
- 【详解01】猫眼电影_简单Java爬虫
- 第三周项目1:个人所得税计算器