二分法

常用排序算法-二分法

冷暖自知 提交于 2020-01-27 15:24:46
整数二分 method 在一个区间内部去区分边界,在选择区间中,要选择答案所在区间,每一次都会将答案覆盖掉。 当区间长度是1的时候区间里的数一定是答案。 Example #include <iostream> using namespace std; const int N = 100010; int n,m; int q[N]; int main() { scanf("%d%d",&n,&m); for (int i = 0; i < n; i ++) scanf("%d",&q[i]); while(m --) { int x; scanf("%d", &x); int l = 0, r = n - 1; while(l < r) { int mid = l + r >> 1; if (q[mid] >= x) r = mid; else l = mid + 1; } if (q[l] != x) cout << "-1 -1" << endl; else { cout << l << ' '; int l = 0,r = n - 1; while(l < r) { int mid = l + r + 1 >> 1; if (q[mid] <= x) l = mid; else r = mid - 1; } cout << l << endl; } } return 0; }

二分法查找的java实现

自闭症网瘾萝莉.ら 提交于 2020-01-27 02:29:52
算法 .二分法 二分法也就是折半查找,在 有序 的数列中查找指定的元素,设定最小索引( low )和最大索引( height-1 )还有中间值mid( (low+height-1)/2 ),这种查找,如果中间值比指定元素小让low=mid+1,如果中间值比指定元素大,让height=mid-1; 以上是大体思路,下面展示两个动图,帮助理解 第一个图表示了二分法的整体过程; 第二个图表示了原方法的整体过程; 观察可得二分法的优越性! 代码实现 import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Scanner; public class Main2 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int arr[] = { 2, 5, 6, 8, 9, 4, 7 }; Arrays.sort(arr); int deix(索引) = getxiabiao(arr, 7); } public static int getxiabiao(int[] arr, int key) { int

1044 Shopping in Mars (25分)/二分法

自闭症网瘾萝莉.ら 提交于 2020-01-26 20:28:58
题目链接 一开始是用的简单模拟的方法做的,有两个测试点超时。于是把cin、cout改为了scanf、printf,可是仍然超时。主要是套了两层循环,时间复杂度为O(n^2)。 看了柳神代码,说要用二分法,于是我又想了想。可是还是每次把求sum的工作放在了函数里面,时间复杂度还是O(n^2)。然后才想到可以在输入时求从第一个数累计求和到当前的数,保存在数组中,这样方便于求子串的和。 用二分法的话这道题的时间复杂度应该是O(nlogn),快了很多。 AC代码 # include <iostream> # include <cstring> using namespace std ; int sum [ 100005 ] , an [ 100005 ] ; int min = 999999999 ; int solve ( int left , int right , int & m ) { int mid , L = left ; while ( left < right ) { mid = ( left + right ) / 2 ; if ( sum [ mid ] - sum [ L - 1 ] >= m ) right = mid ; else left = mid + 1 ; } return left ; } int main ( ) { int n , m ; scanf

C基础算法之二分法查找

僤鯓⒐⒋嵵緔 提交于 2020-01-23 22:48:44
算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的。 基本思想:假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段 中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。 二分法查找在针对大量有序排列的情况下发挥出很优越的效率,这里以最具规律性的数组为例,代码如下: 示例代码: /* binarysearch2.c --- * * Filename: binarysearch2.c * Description: 用循环方式和递归两种方式 实现二分法查找过程 * Author: magc * Maintainer: * Created: 三 7月 25 23:26:52 2012 (+0800) * Version: * Last-Updated: 四 7月 26 00:22:37 2012 (+0800) * By: magc * Update #: 74 * URL: * Keywords: 递归 二分法查找 * Compatibility: * */ /* Commentary: * * * */ /* Change Log: * 添加循环方式和递归方式 * */ /* Code: */ #include <assert.h> #include <ctype.h>

02:二分法求函数的零点

喜你入骨 提交于 2020-01-23 16:53:38
总时间限制: 1000ms 内存限制: 65536kB 描述 有函数: f(x) = x5 - 15 * x4+ 85 * x3- 225 * x2+ 274 * x - 121 已知 f(1.5) > 0 , f(2.4) < 0 且方程 f(x) = 0 在区间 [1.5,2.4] 有且只有一个根,请用二分法求出该根。 输入 无。 输出 该方程在区间[1.5,2.4]中的根。要求四舍五入到小数点后6位。 样例输入 无 样例输出 不提供 # include <iostream> # include <math.h> using namespace std ; double f ( double x ) { return x * x * x * x * x - 15 * x * x * x * x + 85 * x * x * x - 225 * x * x + 274 * x - 121 ; } int main ( ) { double low = 1.5 ; double high = 2.4 ; double mid = ( low + high ) / 2 ; while ( fabs ( f ( mid ) - 0 ) >= 0.000001 ) { if ( f ( mid ) > 0 ) low = mid ; else high = mid ; mid = (

二分法查找

≯℡__Kan透↙ 提交于 2020-01-23 00:24:15
一、简介 二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法。 二分法查找的思路如下: (1)首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。 (2)如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。 (3)如果某一步数组为空,则表示找不到目标元素。 二分法查找的时间复杂度O(logn),优于常规O(n)时间复杂度的算法。 是程序员必须掌握的基础算法之一,在笔试面试中较高频率考察。 二、无重复查找算法 如果数组元素是不重复的(已排序),那么只有一个查找目标。 int binarySearchSingle(vector<int>& array, int target) { int left = 0, right = array.size() - 1; while (left <= right) { int mid = left + (right - left) / 2; if (array[mid] == target) return mid; else if (array[mid] < target) left = mid + 1; else right = mid - 1; } return -1; } 三、有重复查找算法 如果数组元素是不重复的(已排序)

PAT甲级刷题实录——1010

心已入冬 提交于 2020-01-22 20:26:22
原题链接 https://pintia.cn/problem-sets/994805342720868352/problems/994805507225665536 思路 这题是到目前为止比较难的一题,评测系统的通过率也只有 0.11。 首先需要理解基本题意。题目的要求是给一个已知进制的数,求能不能找出一个进制使得另一个未知进制的数在该进制下和已知进制的数数值相等。大部分人应该都会想到将两个数的数值都转换为十进制后做比较。 在理解了基本题意之后,做的过程中发现这题还有不少坑。 进制是没有上限的。不要认为 36 即是最大进制,只是 35 是一位上的最大数字而已。 因为进制没有上限,所以转换为十进制后的数也可能相当相当大,因此用 int 已经不能满足了,需要使用 long long 类型存储进制和数值。 不能用顺序遍历一个个尝试可能的进制,这样的话会运行超时,需要使用二分法寻找进制。二分法查找进制的下界是未知进制数的最大数字 +1,因为每一位的数字都不能超过进制数,比如十进制的数字就只能是 0-9,不可能会有 abcd。二分法查找进制的上界是已知进制数的数值,即假设已知进制数为 6,未知进制数有意义的最小值为 10,这时进制刚好是 6,如果进制比 6 还大的话就不可能和 6 相等,而如果未知进制数比 10 还小那就和进制无关了,因为所有进制个位的单位都是 1。

二分法进阶

最后都变了- 提交于 2020-01-22 20:17:33
在算法竞赛题目中,有两种题型:整数二分、 实数二分。 整数域上的二分, 注意终止边界、左右区间的开闭情况, 避免漏掉答案或者 死循环 。 实数域上的二分, 需要注意精度问题。 之前迷惑了好久的边界问题,在这里总结一下: 整数二分: [ l e f t , r i g h t ] [left,right] [ l e f t , r i g h t ] :分割 [ l e f t , m i d − 1 ] [left,mid-1] [ l e f t , m i d − 1 ] 、 m i d mid m i d 、 [ m i d + 1 , r i g h t ] [mid+1,right] [ m i d + 1 , r i g h t ] ,循环条件 l e f t < = r i g h t left<=right l e f t < = r i g h t [ l e f t , r i g h t ) [left,right) [ l e f t , r i g h t ) :分割 [ l e f t , m i d ) [left,mid) [ l e f t , m i d ) 、 m i d mid m i d 、 [ m i d + 1 , r i g h t ) [mid+1,right) [ m i d + 1 , r i g h t ) ,循环条件 l

Sqli-Labs less 5-6

大憨熊 提交于 2020-01-20 00:31:22
less 5 前置基础知识: 1. left()函数: left(database(),1)=‘s’ left(a,b)从左侧截取a的前b位,正确则返回1,错误则返回0 例如上例中就是先查询database()数据库,从左面看他第一个字母是否是s,如果是则返回1,错误则返回0; 2. regexp函数:select user() regexp ‘r’ user()的结果是root,regexp为匹配root的正则表达式 例如上例中就是把查询到的user用户也就是root和r从左至右进行比较,相同是1,不同是0. 3. like函数: select user() like ‘ro%’ 匹配与regexp相似。 与上个函数类似,唯一不同就是加一个% 4. substr(a,b,c) select substr() XXXX substr(a,b,c)从位置b开始,截取a字符串c位长度 例 如select substr((select database()),1,1)='s’; 匹配第一个字符是否是 s 5. ascii() 将某个字符串转化为ascii值 进入正题: 首先用?id=1试探:(这关依旧是在源码处加入了输出sql语句的代码) 然后输入错误的?id=1‘观察:显示报错,所以一定存在注入漏洞。 再输入:http://192.168.5.100/sqli-labs/Less-5/