编程算法基础-枚举与剪枝
来源:互联网 发布:哪里有淘宝美工培训班 编辑:程序博客网 时间:2024/05/05 07:23
1.2枚举与剪枝
暴力破解虽然简单有效,但是有弱点,考虑的情况很多时,计算机承受不了。
人为排除一些不可能的情况。
剪枝就是为了让计算机尽量避免无用的徒劳的动作。
找零方案
要找8元零钱,有零钞:5元,2元,1元,5角
求所有找零方案。
5角如果写成浮点型的,在计算相等的时候会产生误差,所以全部扩大十倍,再进行比较。
/*要找8元零钱,有零钞:5元,2元,1元,5角求所有找零方案。*/ package ChickRabbit; public class ChargeCash { public static void main(String[] args) { int SUM = 80;// 表示8元 int FIVE = 50; int TWO = 20; int ONE = 10; int FIVEJiao = 5; for (int a = 0; a <= SUM / FIVE; a++) { for (int b = 0; b <= SUM / TWO; b++) { if((SUM-a*FIVE)<0) break;//剪枝 for (int c = 0; c <= SUM / ONE; c++) { if((SUM - (a * FIVE + b * TWO + c * ONE))<0) break; int d = (SUM - (a * FIVE + b * TWO + c * ONE)) / 5; // 5角的个数可以用前面的参数表示出来 if (a * FIVE + b * TWO + c * ONE + d * FIVEJiao == SUM) { System.out.println("可能的找零方案:" + "5元" + a + "张,2元" + b + "张,1元" + c + "张,5角" + d + "张"); } } } } }}
可能的找零方案:5元0张,2元0张,1元0张,5角16张可能的找零方案:5元0张,2元0张,1元1张,5角14张可能的找零方案:5元0张,2元0张,1元2张,5角12张可能的找零方案:5元0张,2元0张,1元3张,5角10张可能的找零方案:5元0张,2元0张,1元4张,5角8张可能的找零方案:5元0张,2元0张,1元5张,5角6张可能的找零方案:5元0张,2元0张,1元6张,5角4张可能的找零方案:5元0张,2元0张,1元7张,5角2张可能的找零方案:5元0张,2元0张,1元8张,5角0张可能的找零方案:5元0张,2元1张,1元0张,5角12张可能的找零方案:5元0张,2元1张,1元1张,5角10张可能的找零方案:5元0张,2元1张,1元2张,5角8张可能的找零方案:5元0张,2元1张,1元3张,5角6张可能的找零方案:5元0张,2元1张,1元4张,5角4张可能的找零方案:5元0张,2元1张,1元5张,5角2张可能的找零方案:5元0张,2元1张,1元6张,5角0张可能的找零方案:5元0张,2元2张,1元0张,5角8张可能的找零方案:5元0张,2元2张,1元1张,5角6张可能的找零方案:5元0张,2元2张,1元2张,5角4张可能的找零方案:5元0张,2元2张,1元3张,5角2张可能的找零方案:5元0张,2元2张,1元4张,5角0张可能的找零方案:5元0张,2元3张,1元0张,5角4张可能的找零方案:5元0张,2元3张,1元1张,5角2张可能的找零方案:5元0张,2元3张,1元2张,5角0张可能的找零方案:5元0张,2元4张,1元0张,5角0张可能的找零方案:5元1张,2元0张,1元0张,5角6张可能的找零方案:5元1张,2元0张,1元1张,5角4张可能的找零方案:5元1张,2元0张,1元2张,5角2张可能的找零方案:5元1张,2元0张,1元3张,5角0张可能的找零方案:5元1张,2元1张,1元0张,5角2张可能的找零方案:5元1张,2元1张,1元1张,5角0张
求n的平方尾数仍为n数本身的数字
/*n位数平方的尾数还是自己*/package ChickRabbit; public class SameNumber { public static void main(String[] args) { // 123*123=.....9 for (int i = 10; i < 100; i++) { int m = i % 10; if (m != 0 && m != 1 && m != 5 && m != 6)//只有结尾是0,1,5,6才可以,两位数以上结尾必须是25,76 continue; int n = i * i;// 平方后 if (n % 100 == i) {// 取余数 System.out.println(i + "," + n); } } }}
25,62576,5776
改进版,10000以内的所有。
/*n位数平方的尾数还是自己*/package ChickRabbit; public class SameNumber { public static void main(String[] args) { // 123*123=.....9 for (int i = 0; i < 10000; i++) { if (i < 10) { int m = i % 10; if (m != 0 && m != 1 && m != 5 && m != 6)// 只有结尾是0,1,5,6才可以 continue; int n = i * i;// 平方后 if (n % 10 == i) {// 取余数 System.out.println(i + "," + n); } } else { int m = i % 100; if (m != 25 && m != 76)//两位数以上结尾必须是25,76 continue; int n = i * i;// 平方后 if (i > 9 && i < 100) { if (n % 100 == i) {// 取余数 System.out.println(i + "," + n); } } else if ( i < 1000) { if (n % 1000 == i) {// 取余数 System.out.println(i + "," + n); } } else if ( i < 10000) { if (n % 10000 == i) {// 取余数 System.out.println(i + "," + n); } } } } }}
0,01,15,256,3625,62576,5776376,141376625,3906259376,87909376
剪枝就是尽早排除逻辑上不符合要求的情况。特别是在循环嵌套中。
观察算式
观察下面的算式:
△△△ * △△ = △△△△
某3位数乘以2位数,结果为4位数
要求:在9个△所代表的数字中,1~9的数字恰好每个出现1次。
/*观察下面的算式:△△△ * △△ = △△△△某3位数乘以2位数,结果为4位数要求:在9个△所代表的数字中,1~9的数字恰好每个出现1次。 */package ChickRabbit; public class Watch { public static void main(String[] args) { int n1, n2, n3, n4, n5, n6, n7, n8, n9; long t1 = System.currentTimeMillis(); for (int i = 123; i <= 987; i++) { n1 = i / 100; n2 = i / 10 % 10; n3 = i % 10; if (n1 == 0 || n2 == 0 || n3 == 0 ) { continue; } if( n1 == n2 || n1 == n3 || n2 == n3){ continue; } for (int j = 12; j <= 98; j++) { n4 = j / 10; n5 = j % 10; if (n4 == 0 || n5 == 0 ) { continue; } if( n4 == n5 || n4 == n1 || n4 == n2 || n4 == n3 || n5 == n1 || n5 == n2 || n5 == n3){ continue; } for (int k = 1234; k <= 9876; k++) { n6 = k / 1000; n7 = k / 100 % 10; n8 = k / 10 % 10; n9 = k % 10; if((n3*n5)%10!=n9){ continue; } if (n6 == 0 || n7 == 0 || n8 == 0 || n9 == 0 || n6 == n7 || n6 == n8 || n6 == n9 || n7 == n8 || n7 == n9 || n8 == n9 || n6 == n1 || n6 == n2 || n6 == n3 || n6 == n4 || n6 == n5 || n7 == n1 || n7 == n2 || n7 == n3 || n7 == n4 || n7 == n5 || n8 == n1 || n8 == n2 || n8 == n3 || n8 == n4 || n8 == n5 || n9 == n1 || n9 == n2 || n9 == n3 || n9 == n4 || n9 == n5) { continue; } if (i * j == k) { System.out.println(i + " " + j + " " + k); } } } } long t2 = System.currentTimeMillis(); System.out.println(t2 - t1); }}
138 42 5796157 28 4396159 48 7632186 39 7254198 27 5346297 18 5346483 12 57968017慢的一逼
改进一下:
/*观察下面的算式:△△△ * △△ = △△△△某3位数乘以2位数,结果为4位数要求:在9个△所代表的数字中,1~9的数字恰好每个出现1次。 */package ChickRabbit; public class Watch { public static void main(String[] args) { int n1, n2, n3, n4, n5, n6, n7, n8, n9; long t1 = System.nanoTime();// 测试时间的第一个时间点 for (int i = 123; i <= 987; i++) { n1 = i / 100; n2 = i / 10 % 10; n3 = i % 10; if (n1 == 0 || n2 == 0 || n3 == 0 || n1 == n2 || n1 == n3 || n2 == n3) { continue; } for (int j = 12; j <= 98; j++) { int k = i * j;// 得到4位数的乘积,先得到乘积并对乘积范围进行判断,再取每一位数字,可以提高效率。 if (k <= 9876) { // 对第二个乘数进行判断 n4 = j / 10; n5 = j % 10; if (n4 == 0 || n5 == 0) { continue; } if (n4 == n5 || n4 == n1 || n4 == n2 || n4 == n3 || n5 == n1 || n5 == n2 || n5 == n3) { continue; } // 对乘积进行判断 n6 = k / 1000; n7 = k / 100 % 10; n8 = k / 10 % 10; n9 = k % 10; if ((n3 * n5) % 10 != n9 || n6 == 0 || n7 == 0 || n8 == 0 || n9 == 0 || n6 == n7 || n6 == n8 || n6 == n9 || n7 == n8 || n7 == n9 || n8 == n9 || n6 == n1 || n6 == n2 || n6 == n3 || n6 == n4 || n6 == n5 || n7 == n1 || n7 == n2 || n7 == n3 || n7 == n4 || n7 == n5 || n8 == n1 || n8 == n2 || n8 == n3 || n8 == n4 || n8 == n5 || n9 == n1 || n9 == n2 || n9 == n3 || n9 == n4 || n9 == n5) { continue; } System.out.println(i + "*" + j + "=" + k); } } } long t2 = System.nanoTime();// 测试时间的第二个时间点 System.out.println(t2 - t1); }}
138*42=5796157*28=4396159*48=7632186*39=7254198*27=5346297*18=5346483*12=57963043679
改进版2,将判断0的或运算换为乘法。(不知道哪个效率高)
/*观察下面的算式:△△△ * △△ = △△△△某3位数乘以2位数,结果为4位数要求:在9个△所代表的数字中,1~9的数字恰好每个出现1次。 */package ChickRabbit; public class Watch { public static void main(String[] args) { int n1, n2, n3, n4, n5, n6, n7, n8, n9; long t1 = System.nanoTime();// 测试时间的第一个时间点 for (int i = 123; i <= 987; i++) { n1 = i / 100; n2 = i / 10 % 10; n3 = i % 10; if (n1 * n2 * n3 == 0 || n1 == n2 || n1 == n3 || n2 == n3) { continue; } for (int j = 12; j <= 98; j++) { int k = i * j;// 得到4位数的乘积,先得到乘积并对乘积范围进行判断,再取每一位数字,可以提高效率。 if (k <= 9876) { // 对第二个乘数进行判断 n4 = j / 10; n5 = j % 10; if (n4 * n5 == 0 || n4 == n5 || n4 == n1 || n4 == n2 || n4 == n3 || n5 == n1 || n5 == n2 || n5 == n3) { continue; } // 对乘积进行判断 n6 = k / 1000; n7 = k / 100 % 10; n8 = k / 10 % 10; n9 = k % 10; if ((n3 * n5) % 10 != n9 || n6 * n7 * n8 * n9 == 0 || n6 == n7 || n6 == n8 || n6 == n9 || n7 == n8 || n7 == n9 || n8 == n9 || n6 == n1 || n6 == n2 || n6 == n3 || n6 == n4 || n6 == n5 || n7 == n1 || n7 == n2 || n7 == n3 || n7 == n4 || n7 == n5 || n8 == n1 || n8 == n2 || n8 == n3 || n8 == n4 || n8 == n5 || n9 == n1 || n9 == n2 || n9 == n3 || n9 == n4 || n9 == n5) { continue; } System.out.println(i + "*" + j + "=" + k); } } } long t2 = System.nanoTime();// 测试时间的第二个时间点 System.out.println(t2 - t1); }}
138*42=5796157*28=4396159*48=7632186*39=7254198*27=5346297*18=5346483*12=57963038033
1 0
- 编程算法基础-枚举与剪枝
- 算法基础-枚举与剪枝_观察算式
- 算法基础——1.2枚举与剪枝
- 算法思想:枚举与剪枝
- 枚举与剪枝算法学习笔记
- 算法基础——1.2枚举与剪枝(找零钱、n位数平方的尾数还是自己)
- 枚举 编程题#1: 画家问题(Coursera 程序设计与算法 专项课程4 算法基础 郭炜、刘家瑛;二进制实现)
- 决策树算法与剪枝处理
- 算法基础-枚举-编程题#1: 画家问题
- 算法基础:1枚举
- 算法基础---枚举案例
- 第01讲-枚举与剪枝_观察算式
- 决策树之剪枝原理与CART算法
- 决策树算法与不同的剪枝方法
- 编程基础之 数据结构与算法
- 编程算法基础-2.6加密与解密
- Java编程算法基础--加密与解密
- Java编程算法基础---组合与聚合
- linux下实时查看tomcat运行日志
- 关于WindowsServer2012 R2的使用
- 高中数学排列组合公式/排列组合计算公式
- 在不刷新页面的情况下调用远程asp脚本
- 调用百度地图实现在地图上定位
- 编程算法基础-枚举与剪枝
- 堆的相关知识——创建堆
- ASP+与ASP有什么不同
- 显卡排名图(偶也是在网上看到的,特提供给广大网友)
- Python List、Dict等的sort与sorted排序
- Longest Common Prefix
- 计算机视觉方向的顶级会议、期刊
- System.Data.Linq中的一些简单函数的使用
- 腾讯2014年实习生招聘试题