蛮力法策略--枚举
来源:互联网 发布:古代吃人 知乎 编辑:程序博客网 时间:2024/06/16 04:36
蛮力法
蛮力法是利用计算机运行速度快这一个特性。把问题所有的情况或所有的过程交给计算机逐一尝试,从中找出问题的解。
策略:枚举(穷举)
根据问题的条件将可能的情况一 一列举起来,逐一尝试找出问题的解。有时问题的规模太大,可以排除一些明显不合理的情况。
枚举法的一般规律:
找出枚举范围:分析问题所涉及的所有情况。找出约束条件:分析问题的解需要满足的条件,并用逻辑表达式解释。对枚举法的优化主要是对约束范围和约束条件的数学优化。
百钱百鸡
问题:
我国古代数学家张丘建在《算经》一书中提出的数学问题:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
分析:
隐含约束条件:Z%3 = 0,因为鸡肯定是整只的(肯德鸡除外)。所以鸡仔的个数是3的倍数。
算法:
注意:计算机中遇到除法要小心!
/* Name: Copyright: Author: Date: 20/12/17 17:26 Description: 百钱百鸡问题 */#include <stdio.h>#include <stdlib.h>void Two(){ int x,y; //枚举次数2000/3 for(x=0;x<100/5;x++){//约束范围 for(y=0;y<100/3;y++){//约束范围 if(x*5+y*3+(100-x-y)/3==100&&(100-x-y)%3==0){//约束条件 printf("%d翁%d母%d雏\n",x,y,100-x-y); } } } printf("-----\n");} int main(){ Two();//约束范围的变化可以大大提高效率,精简约束条件 int x,y,z; //枚举次数是20万次 for(x=0;x<=100/5;x++){//约束范围 for(y=0;y<=100/3;y++){//约束范围 for(z=0;z<100*3;z++){//约束范围 if(x+y+z==100&&x*5+y*3+z/3==100&&z%3==0){//约束条件 printf("%d翁%d母%d雏\n",x,y,z); } } } } system("pause"); return 0;}
百钱百鸡的数学优化
算式迷问题
问题:
解算式迷: A B C A B X A -------------- D D D D D D
分析:
不同的枚举对象,算法的效率不一样。
算法:
/* Name: Copyright: Author: Date: 20/12/17 18:06 Description: 解算式迷: A B C A B X A -------------- D D D D D D */#include <stdlib.h>#include <stdio.h>//选择不同的枚举对象,算法效率有显著的差别,枚举对象可以从各个角度去考虑 void Two(){ //63次枚举 int D,A; for(D=1;D<=9;D++){ for(A=3;A<=9;A++){ long e = D*100000+D*10000+D*1000+D*100+D*10+D; if(e%A==0){ long F = e/A; if(F/10000==A&&(F/10)%10==A&&F%10==(F/1000)%10){ printf("A:%d B:%d C:%d D:%d\n",A,F%10,F/100%10,D); } } } } } int main(){ Two(); int A,B,C,D; //枚举次数700 for(A=3;A<=9;A++){//枚举范围 for(B=0;B<=9;B++){//枚举范围 for(C=0;C<=9;C++){//枚举范围 //约束条件的判断 long temp = A*10000+B*1000+C*100+A*10+B; long e = temp*A; int x = e%10; e = e/10; int i=0; for(i=1;i<=5;i++){ int m = e%10; e = e/10; if(m!=x) break; } if(i==6){ D = x; printf("A:%d B:%d C:%d D:%d\n",A,B,C,D); } } } } system("pause"); return 0;}
暴力最小公倍数
问题:
求出三分二数字的最小公倍数。
分析:
最小公倍数的定义是:一个整数的所有倍数中最小的一个。在问题规模很小的时候,可以选择三个数中最大的枚举其倍数,判断是否是其他两个数的倍数,最小的一个就是三个数的最小公倍数。
算法:
/* Name: Copyright: Author: Date: 20/12/17 19:03 Description: 暴力枚举三个数的最小公倍数 */#include <stdio.h>#include <stdlib.h>int main(){ int a,b,c; scanf("%d %d %d",&a,&b,&c); for(int i=1;;i++){ if(a*i%b==0&&a*i%c==0){ printf("%d %d %d这三个数的最小公倍数是:%d\n",a,b,c,a*i);break; } } system("pause"); return 0;}
狱史问题
问题:
某国王对囚犯进行大赦,让一狱吏n次通过一排锁着的n间牢房,每通过一次,按所定规则转动n间牢房中的某些门锁, 每转动一次, 原来锁着的被打开, 原来打开的被锁上;通过n次后,门锁开着的,牢房中的犯人放出,否则犯人不得获释。
转动门锁的规则是这样的,第一次通过牢房,要转动每一把门锁,即把全部锁打开;第二次通过牢房时,从第二间开始转动,每隔一间转动一次;第k次通过牢房,从第k间开始转动,每隔k-1 间转动一次;问通过n次后,哪些牢房的锁仍然是打开的?
输入
狱吏通过牢房的次数n和牢房的间数n(n<=32767)。
输出:被释放的犯人的房间号
分析:
题目中锁的状态只有两个:开 关,可以用一维数组来模拟锁的状态。
使用数学运算模拟开关锁:a[i] = 1-a[i]
枚举问题中所有的过程,最终的状态就是问题的解。
算法:
/* Name: Copyright: Author: Date: 20/12/17 19:03 Description: 狱史问题 */#include <stdio.h>#include <stdlib.h>int main(){ int n; scanf("%d",&n); int *a; a = (int *)malloc(sizeof(int)*(n)); for(int i=0;i<n;i++){ a[i] = 1; } //把所有可能的过程枚举出来 for(int i=1;i<=n;i++){ for(int j=i-1;j<n;j = j+i){ a[j] = 1-a[j]; } } for(int i=0;i<n;i++){ if(a[i]==0){ printf("%d号监狱释放!\n",i+1); } } system("pause"); return 0;}
- 蛮力法策略--枚举
- 策略枚举
- 策略枚举应用
- 策略枚举模式
- java策略枚举
- java 策略枚举
- 算法---枚举策略
- 算法--枚举策略
- 算法--枚举策略
- 算法--枚举策略
- 策略模式(政策模式) 策略枚举
- 【数学{枚举策略}】有理逼近
- JAVA枚举类状态机 与 Java枚举策略模式
- 策略模式的扩展——策略枚举
- 策略模式的扩展——策略枚举
- 策略模式的扩展——策略枚举
- 策略模式的扩展——策略枚举
- 枚举与单例和策略
- 1006. 换个格式输出整数 (15)-浙大PAT乙级真题java实现
- 【高等数学】极限计算&中值定理&多元函数微分学
- HTML表单颜色选择器
- 在eclipse中修改maven插件
- 线程池最优大小
- 蛮力法策略--枚举
- Atcoder 500 FT Robot DP
- JavaScript~ajax~城市列表获取天气
- Java练习题第一套知识点
- iOS用户行为统计工具开发-无侵入埋点
- linux服务器 Mysql
- Apache POI操作excel
- linux的文件资源管理
- SpringSecurity笔记二