挑战程序设计 1.1 抽签
原文:https://bafanglvren.ink/archives/21/
题目
你的朋友提议玩一个游戏:将写有数字的n 个纸片放入口袋中,你可以从口袋中抽取4 次纸片,每次记下纸片上的数字后都将其放回口袋中。如果这4 个数字的和是m,就是你赢,否则就是你的朋友赢。你挑战了好几回,结果一次也没赢过,于是怒而撕破口袋,取出所有纸片,检查自己是否真的有赢的可能性。请你编写一个程序,判断当纸片上所写的数字是k1,k2, …, kn 时,是否存在抽取4 次和为m 的方案。如果存在,输出Yes;否则,输出No。
限制条件
1 ≤ n ≤ 50
1 ≤ m ≤ 108
1 ≤ ki ≤ 108
输入
n = 3
m = 10
k = {1, 3, 5}
输出
Yes(例如4次抽取的结果是1、1、3、5,和就是10)
枚举解
import java.util.Scanner;public class Main {static int n;static int m;static int[] k;static Scanner cin;static boolean f = false;public static void main(String[] args) {cin = new Scanner(System.in);//输入n = cin.nextInt();m = cin.nextInt();k = new int[n];for (int i = 0; i < n; i++) {k[i] = cin.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)f = true;}}}}//输出if (f)System.out.println("Yes");elseSystem.out.println("No");}}
简单的穷举。
但这只是1<=n<=50,如果将条件改为1<=n<=1000,那么代入枚举的复杂度n4也就是1012次,这个程序的速度是远远不够的。
使用二分查找
仔细观察最后一重循环,做的事情就是检查数组k是否存在k[d]使得k[a] + k[b] + k[c] + k[d] = m成立。
对其进行移项:
k[d] = m - k[a] - k[b] - k[c]
其实就是在数组k里面查找是否存在x = m - k[a] - k[b] - k[c]
既然是查找,就可以使用二分查找(log n)进行替换。注意先对k进行排序
import java.util.Arrays;
import java.util.Scanner;public class Main2 {static int n;static int m;static int []k;static Scanner cin;static boolean f = false;public static void main(String[] args) {cin = new Scanner(System.in);//输入n = cin.nextInt();m = cin.nextInt();k = new int[n];for(int i = 0;i<n;i++) {k[i] = cin.nextInt();}//排序Arrays.sort(k);//三重枚举+二分查找for(int a = 0;a<n;a++) {for(int b = 0;b<n;b++) {for(int c = 0;c<n;c++) {//在数组k中查找xint x = m - k[a] - k[b] - k[c];if(binarySearch(x)) {f = true;}}}}//输出if(f)System.out.println("Yes");elseSystem.out.println("No");}public static boolean binarySearch(int x) {int left = 0,right = k.length-1;int mid = (left + right)/2;while(right - left >=1) {if(k[mid] == x) {return true;}else if (k[mid] < x) {left = mid + 1;}else {right = mid - 1;}}return false;}}
这里使用了java自带的快速排序Arrays.sort(),也可以自己实现。java也提供了自带的二分查找
public static int binarySearch(int[] a,int key)
Arrays.binarySearch(k, x);
如果数组中存在该元素,则会返回该元素在数组中的下标
如果数组中不存在该元素,则会返回 -(插入点 + 1)
得到了复杂度为n^3logn的抽签算法。
挑战程序设计 1.1 抽签相关推荐
- 挑战程序设计竞赛(第2版)》
<挑战程序设计竞赛(第2版)> 基本信息 作者: (日)秋叶拓哉 岩田阳一 北川宜稔 译者: 巫泽俊 庄俊元 李津羽 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9787 ...
- 《挑战程序设计竞赛》 读后感(转载)
<挑战程序设计竞赛> 读后感 最近要开始准备面试找工作,算法是准备的重中之重,舍友推荐了<挑战程序设计竞赛>这本书.花了一周的时间大体过了一遍,该书真切地让我理解了" ...
- 《挑战程序设计竞赛(第2版)》习题册攻略
本项目来源于GitHub 链接: 项目GitHub链接 1 前言 项目为<挑战程序设计竞赛(第2版)>习题册攻略,已完结.可配合书籍或笔记,系统学习算法. 题量:约200道,代码注释内含详 ...
- POJ 1150 The Last Non-zero Digit 《挑战程序设计竞赛》
为什么80%的码农都做不了架构师?>>> POJ 1150 The Last Non-zero Digit超大组合数:求超大组合数P(n, m)的最后一个非零位.4.1更加复杂 ...
- POJ 3735 Training little cats 题解 《挑战程序设计竞赛》
为什么80%的码农都做不了架构师?>>> POJ 3735 Training little cats调教猫咪:有n只饥渴的猫咪,现有一组羞耻Play,由k个操作组成,全部选自: ...
- POJ 3608 Bridge Across Islands 《挑战程序设计竞赛》
为什么80%的码农都做不了架构师?>>> POJ 3608 Bridge Across Islands跨岛大桥:在两个凸包小岛之间造桥,求最小距离?3.6与平面和空间打交道的计 ...
- AOJ 1312 Where's Wally 题解《挑战程序设计竞赛》
为什么80%的码农都做不了架构师?>>> 本文由码农场 同步,最新版本请查看原文:http://www.hankcs.com/program/algorithm/aoj-131 ...
- ICPC程序设计题解书籍系列之三:秋田拓哉:《挑战程序设计竞赛》(第2版)
白书<挑战程序设计竞赛>(第2版)题目一览 白书:秋田拓哉:<挑战程序设计竞赛>(第2版) 第1章 蓄势待发--准备篇(例题) POJ1852 UVa10714 ZOJ2376 ...
- 挑战程序设计竞赛——详解DFS及BFS
挑战程序设计竞赛--详解DFS及BFS 一.学会要用到的stl函数,Stack.Quene.Pair 1.Stack(DFS隐式的用到,并与Queue对比记忆) 头文件==#include== sta ...
最新文章
- History(历史)命令用法
- 鸿蒙系统手机mate40,鸿蒙系统来了!华为Mate40首批,2年前手机将被淘汰
- 问题集锦(1-10)
- Source Generators(源代码生成器)的调试器支持 | Visual Studio 2019(16.10)新功能试用...
- 《Head First设计模式》 读书笔记16 其余的模式(二) 蝇量 解释器 中介者
- 借助钉钉宜搭,奶茶店开始用黑科技管理门店了
- Android P 开发者预览版
- SVM多分类原理学习
- ug10.0安装好了怎么找到
- 人人,金山西山居,腾讯互娱,微信,网易游戏offer及面经(转)
- 非战之罪,从永中Office谈起
- 关于前端架构的过去、现在与未来
- 小米9开发版已开启Android,小米9迎来最后一个基于安卓9的系统,即将启动安卓q开发版内测...
- hread first html5,(完整版)2017届上海市徐汇区高三英语二模卷(含听力文本和答案)...
- LearnOpenGL 入门—摄像机
- 消防工程师 第二篇 建筑防火 1.厂房和仓库的火灾危险性分类
- [单片机学习笔记](35):串级PID算法应用剖析、通过串口控制电机、MPU6050获取平衡车姿态、自制平衡车PID算法程序设计
- 渣渣一记:)之HTML
- 论如何提升学习的能力
- android左侧抽屉,Android控件之左侧抽屉菜单