基于二分查找的抽签游戏算法的优化

问题描述:

一个袋子里有n个纸片,纸片上有数字,你随机取出4张纸(有放回),若四张纸的数字和为m,你就赢了,否则你就输了。连续试了几次后你都失败了,于是你想知道到底有没有赢的例子。(n:1到50; m和k[i] 1到10的8次方)

输入输出样例:

输入:

n=3

m=10

k={1,3,5}

输出:yes(1+1+3+5=10)

输入

n=3

m=9

k={1,3,5}

输出:

No

复杂度为N的四次方

复杂度为N的四次方算法分析:

通过四重循环来枚举所有情况。

复杂度为N的四次方算法实现:

package com.renyou.算法;import java.util.Scanner;
/*** m=k[a]+k[b]+k[c]+k[d]* @author 刘仁有* (10的8次方=>m=>1)*  (50=>n>=1)*  (10的8次方=>k[i]=>1)*  */
public class 抽签复杂度N的4次方 {private final int MAX_N=50;public static void main(String[] args) {new 抽签复杂度N的4次方().抽签();}public void 抽签(){int m,n;int[] k;Scanner scanner=new Scanner(System.in);m=scanner.nextInt();n=scanner.nextInt();k=new int[n];for(int i=0;i<n;i++){k[i]=scanner.nextInt();}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(k[a]+k[b]+k[c]+k[d]==m)System.out.println("找到了这四个值,分别是:"+k[a]+";"+k[b]+";"+k[c]+";"+k[d]);}}}}}
}

复杂度为N的三次方LogN

复杂度为N的三次方LogN的算法分析:

检查是否有k[d]使得k[d]=m-k[a]-k[b]-k[c]

复杂度为N的三次方LogN的算法实现:

package com.renyou.算法;import java.util.Scanner;/*** k[d]=m-k[a]-k[b]-k[c]* @author 刘仁有 (10的8次方=>m=>1) (1000=>n>=1) (10的8次方=>k[i]=>1)* */
public class 抽签复杂度N的三次方LogN {private final int MAX_N = 1000;private int[] k ;public static void main(String[] args) {new 抽签复杂度N的三次方LogN().抽签();}public void 抽签() {int m, n;/******** 控制台输入数据 **********/Scanner scanner = new Scanner(System.in);m = scanner.nextInt();n = scanner.nextInt();k=new int[n];for (int i = 0; i < n; i++) {k[i] = scanner.nextInt();}/********** 数组快速排序 **************/sort(k, 0, k.length - 1);/*********** N的三次方的for循环 ***************/for (int a = 0; a < n; a++) {for (int b = 0; b < n; b++) {for (int c = 0; c < n; c++) {if(bineary_search(m-k[a]-k[b]-k[c])){System.out.println("找到了这四个值,分别是:"+k[a]+";"+k[b]+";"+k[c]+";"+(m-k[a]-k[b]-k[c]));}}}}}/*** * @param 要查找的值* @return ture or false*/public boolean bineary_search(int value) {int low = 0;int high = k.length - 1;while (low <= high) {int mid = (low + high) / 2;int midValue = k[mid];if (value < midValue) {high = mid - 1;} else if (value > midValue) {low = mid + 1;} else {return true;}}return false;}/*** 快速排序* * @param array*            待快速排序数组* @param first*            待快速排序序列的最左边所在位置* @param end*            待快速排序序列的最右边所在位置*/public void sort(int[] array, int first, int end) {int pivot = 0;// 轴值记录所在位置if (first < end) {// 区间长度大于一才会执行一次划分,否则递归结束pivot = partition(array, first, end);// 进行一次划分sort(array, first, pivot - 1);// 递归地对左序列进行快速排序sort(array, pivot + 1, end);// 递归地对右序列进行快速排序}}/*** 快速排序一次划分算法* * @param array*            待快速排序数组* @param first*            待快速排序序列的最左边所在位置* @param end*            待快速排序序列的最右边所在位置* @return 每次划分序列轴值最后记录所在位置*/public int partition(int[] array, int first, int end) {while (first < end) {while (first < end && array[first] <= array[end]) {// 右侧扫描end--;}if (first < end) {swap(array, first, end);first++;}while (first < end && array[first] <= array[end]) {// 左侧扫描first++;}if (first < end) {swap(array, end, first);end--;}}return first;}/*** * @param array*            待交换数组* @param i*            待交换数组的一个索引* @param j*            待交换数组的另一个索引*/public void swap(int[] array, int i, int j) {int temp = array[i];array[i] = array[j];array[j] = temp;}
}

复杂度为N的二次方LogN

复杂度为N的二次方LogN的算法分析:

检查是否有k[c]+k[d]使得k[c]+k[d]=m-k[a]-k[b]

复杂度为N的二次方LogN的算法实现:

package com.renyou.算法;import java.util.Scanner;/*** k[c]+k[d]=m-k[a]-k[b]* * @author 刘仁有 (10的8次方=>m=>1) (1000=>n>=1) (10的8次方=>k[i]=>1)* */
public class 抽签复杂度N的二次方LogN {private final int MAX_N = 1000;private int[] k;private int[] kcd;// 存储 c和d的和的数组public static void main(String[] args) {new 抽签复杂度N的二次方LogN().抽签();}public void 抽签() {int m, n;/******** 控制台输入数据 **********/Scanner scanner = new Scanner(System.in);m = scanner.nextInt();n = scanner.nextInt();k = new int[n];for (int i = 0; i < n; i++) {k[i] = scanner.nextInt();}/*********** 存储 c和d的和 **********/kcd = new int[n * n];for (int c = 0; c < n; c++) {for (int d = 0; d < n; d++) {kcd[c * n + d] = k[c] + k[d];}}/********** kcd数组快速排序 **************/sort(kcd, 0, kcd.length - 1);/*********** N的三次方的for循环 ***************/for (int a = 0; a < n; a++) {for (int b = 0; b < n; b++) {if (bineary_search(m - k[a] - k[b])) {System.out.println("找到了这四个值");}}}}/*** * @param 要查找的值* @return ture or false*/public boolean bineary_search(int value) {int low = 0;int high = kcd.length - 1;while (low <= high) {int mid = (low + high) / 2;int midValue = kcd[mid];if (value < midValue) {high = mid - 1;} else if (value > midValue) {low = mid + 1;} else {return true;}}return false;}/*** 快速排序* * @param array*            待快速排序数组* @param first*            待快速排序序列的最左边所在位置* @param end*            待快速排序序列的最右边所在位置*/public void sort(int[] array, int first, int end) {int pivot = 0;// 轴值记录所在位置if (first < end) {// 区间长度大于一才会执行一次划分,否则递归结束pivot = partition(array, first, end);// 进行一次划分sort(array, first, pivot - 1);// 递归地对左序列进行快速排序sort(array, pivot + 1, end);// 递归地对右序列进行快速排序}}/*** 快速排序一次划分算法* * @param array*            待快速排序数组* @param first*            待快速排序序列的最左边所在位置* @param end*            待快速排序序列的最右边所在位置* @return 每次划分序列轴值最后记录所在位置*/public int partition(int[] array, int first, int end) {while (first < end) {while (first < end && array[first] <= array[end]) {// 右侧扫描end--;}if (first < end) {swap(array, first, end);first++;}while (first < end && array[first] <= array[end]) {// 左侧扫描first++;}if (first < end) {swap(array, end, first);end--;}}return first;}/*** * @param array*            待交换数组* @param i*            待交换数组的一个索引* @param j*            待交换数组的另一个索引*/public void swap(int[] array, int i, int j) {int temp = array[i];array[i] = array[j];array[j] = temp;}
}

基于二分查找的抽签游戏算法的优化相关推荐

  1. Leetcode中几道二分查找(Binary Search)的算法题总结

    二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列.二分查找法的时间复杂度是对数级别的,O(lo ...

  2. python实现二分查找_数据结构和算法:Python实现二分查找(Binary_search)

    在一个列表当中我们可以进行线性查找也可以进行二分查找,即通过不同的方法找到我们想要的数字,线性查找即按照数字从列表里一个一个从左向右查找,找到之后程序停下.而二分查找的效率往往会比线性查找更高. 一. ...

  3. 二分查找的时间复杂度以及算法

    ​ 给定一个规模为n的按照数字从小到大排序的数组,快速查询x元素在数组中的位置 示例: 数组:[1,3,6,9,14,35,67] 查找的值:9输出:3 1.计算数据规模为n二分查找的时间复杂度 循环 ...

  4. d - 数据结构实验之查找四:二分查找_数据结构与算法笔记

    二分查找(上):如何用最省内存的方式实现快速查找功能? 二分查找(下):如何快速定位IP对应的省份地址? 变体一:查找第一个值等于给定值的元素 变体二:查找最后一个值等于给定值的元素 变体三:查找第一 ...

  5. 基于多种群机制的PSO算法(优化与探索三 *混合种群思想优化多种群与广义PSO求解JSP)

    文章目录 前言 版权 2022.6.22 混合PSO优化 对比 猜想 完整代码 广义PSO解决JSP问题 JSP问题 数据定义 DNA编码 广义PSO执行 合适的策略选择粒子 对比 完整编码 前言 本 ...

  6. java 二分查找_计算机入门必备算法——二分查找法

    1.引言 笔者对于计算机的研究一直停滞不前,近期想对一些算法进行复习和进一步的研究,每天都会更新一个新的算法,算法有难有易,层层递进.不希望能学的有多么高深,只希望在一些最基本的算法上有编码的思路,或 ...

  7. 小白的算法初识课堂(part1)--二分查找法

    学习笔记 学习书目:<算法图解>- Aditya Bhargava 二分查找法 算法是一组完成任务的指令,任何代码片段都可视为算法.二分查找是一种算法,其输入是一个有序的元素列表(必须有序 ...

  8. 语言非递归求解树的高度_算法素颜(11):无死角“盘”它!二分查找树

    引言 <菜鸟也能"种"好二叉树!>一文中提到了:为了方便查找,需要进行分层分类整理.而满足这种目标的数据结构之一就是树. 树的叶子节点可以看作是最终要搜寻的目标物:叶子 ...

  9. codeforces 贪心+优先队列_算法基础04-深度优先搜索、广度优先搜索、二分查找、贪心算法...

    深度优先搜索DFS.广度优先搜索BFS 比较 拿谚语打比方的话,深度优先搜索可以比作打破砂锅问到底.不撞南墙不回头:广度优先搜索则对应广撒网,多敛鱼 两者没有绝对的优劣之分,只是适用场景不同 当解决方 ...

最新文章

  1. QT学习:网络应用开发练习(文件下载)
  2. c语言 函数多个参数,C语言函数可变参数
  3. oracle几个状态,oracle启动的四个状态
  4. VC++ ToolTip的简单使用
  5. JS判断浏览器类型与版本
  6. 我的微博,三层嵌套,
  7. HTML5期末大作业:动漫网站设计——千与千寻(10页) 含设计报告 HTML+CSS+JavaScript 学生动漫网页设计模板下载 海贼王大学生HTML网页制作作品
  8. 15套前端经典实战项目大合集,小白练手必备实战项目
  9. 【锂电】锂电工艺大全
  10. 可汗学院公开课:统计学笔记——中心极限定理、置信区间
  11. 服务器系统日志保留时间设置,服务器行为操作日志
  12. 自定义指令,实现默认头像和用户上传头像的切换
  13. 太阳能电池板自动清洗机器人的制作分享
  14. Ipmitool工具安装以及常见使用方法
  15. 125家单位联合完成微生物组实验手册(Microbiome Protocol eBook)第1版
  16. 5年来做QQ与QQ群营销所走过的坑、奉劝大家别再在这块上花心思了
  17. 财会法规与职业道德【7】
  18. soapui 证书_配置https双向认证,以及用soapui调试
  19. 好用的Excel拆分工具
  20. 平摊分析(Amortized Analysis)-- Potential Method

热门文章

  1. 钟形曲线 matlab_打破钟形曲线:在同一个海洋中脱颖而出
  2. 工具化、产品化、运营化—「美团点评」运维的故事
  3. MIR DATABANK自动化和智能制造每周要闻 —2019年10月15日
  4. 新闻文本分类 TextCNN
  5. 4-使用GitHub(Github Issue)及基本概念实战
  6. 凡客诚品站点打不开:页面显示域名到期了!
  7. 《第七天》之第五天每个故事都有一个悲伤的内核
  8. twain数据转换为QImage
  9. 新编计算机科学概论考试,新编计算机科学概论-刘艺蔡敏-习题与答案
  10. 第16课 Altium Designer20(AD20)+VESC6.4实战教程:总体布局和定义板子边框 (第一版)(北冥有鱼)