分治法(实战篇之二分查找)

啥也不说,先上题!!!

二分查找

Description

给你n个整数和一个整数k。问:n个数中是否存在整数k,如果存在,输出“Yes”,否则输出“No”。

Input

输入包含多组测试用例,对于每组测试用例:

输入一个数字n (1 <= n <= 10^7)

接下来输入n个不同的数字Ai( |Ai| <= 10^7)。

接下来输入整数k ( |k| <= 10^7)。代表要找的数字k

Output

n个数中是否存在整数k,如果存在输出“Yes”,否则输出“No”。每组数据占一行。

Sample Input 1

5
-100 1 2 3 4
-100
5
1 2 3 5 6
4

Sample Output 1

Yes
No

看起来很简单,对吧?让我们来小试牛刀一下!!!first blood我比着思想篇写了二分法的代码,运行着似乎没啥问题,结果wa了
bool Binary_search(int A[], int lo, int hi, int k){
    if(lo > hi){
        return false;
    }
    else{
        int mi = (lo + hi) >> 1;
        if(A[mi] == k){
            return true;
        }
        else if(A[mi] > k){
            Binary_search(A, lo, mi - 1, k);
        }
        else{
             Binary_search(A, mi + 1, hi, k);
        }

    }

}//分析复杂度:首先该函数在主函数中调用了 logn 次,           //该函数又在主函数的for循环里(0~n-1)       //所以复杂度为nlogn

second  blood

超时??我明明把递归改成while循环了,神马情况??

#include <bits/stdc++.h>
using namespace std;
int A[10000005];
//bool Binary_search(int A[], int lo, int hi, int k){
//    if(lo > hi){
//        return false;
//    }
//    else{
//        int mi = (lo + hi) >> 1;
//        if(A[mi] == k){
//            return true;
//        }
//        else if(A[mi] > k){
//            Binary_search(A, lo, mi - 1, k);
//        }
//        else{
//            Binary_search(A, mi + 1, hi, k);
//        }
//
//    }
//
//}
bool Binary_search(int lo, int hi, int k){
    while(lo <= hi){
        int mi = (lo + hi) >> 1;
        if(A[mi] == k){
            return true;
        }
        else if(A[mi] > k){
            hi = mi - 1;
        }
        else{
            lo = mi + 1;
        }
    }
    return false;
}
int main(){

    int n;

    while(cin >> n){
        for(int i = 0; i < n; i++){
            cin >> A[i];
        }
        int k;
        cin >> k;
        sort(A, A + n);
        if(Binary_search(0, n - 1, k)){
            cout << "Yes" << endl;
        }
        else{
            cout << "No" << endl;
        }

    }

    return 0;
}

经过一番思索.......

是不是卡时间,毕竟输入输出流比格式输入输出更耗时

此时我们需要 开 !外 !挂!// std::ios::sync_with_stdio(false);

#include <bits/stdc++.h>
using namespace std;
int A[10000005];
//bool Binary_search(int A[], int lo, int hi, int k){
//    if(lo > hi){
//        return false;
//    }
//    else{
//        int mi = (lo + hi) >> 1;
//        if(A[mi] == k){
//            return true;
//        }
//        else if(A[mi] > k){
//            Binary_search(A, lo, mi - 1, k);
//        }
//        else{
//            Binary_search(A, mi + 1, hi, k);
//        }
//
//    }
//
//}
bool Binary_search(int lo, int hi, int k){
    while(lo <= hi){
        int mi = (lo + hi) >> 1;
        if(A[mi] == k){
            return true;
        }
        else if(A[mi] > k){
            hi = mi - 1;
        }
        else{
            lo = mi + 1;
        }
    }
    return false;
}
int main(){
    std::ios::sync_with_stdio(false);//代表把 std(standard) ios(iostream)和 stdio(standard input output)同时发生(sync)的按钮关掉
    int n;
    while(cin >> n){
        for(int i = 0; i < n; i++){
            cin >> A[i];
        }
        int k;
        cin >> k;
        sort(A, A + n);
        if(Binary_search(0, n - 1, k)){
            cout << "Yes" << endl;
        }
        else{
            cout << "No" << endl;
        }

    }

    return 0;
}

accept

快夸我!!!嘻嘻

原文地址:https://www.cnblogs.com/nibaba131237/p/12327455.html

时间: 2024-11-05 22:48:26

分治法(实战篇之二分查找)的相关文章

基础算法之二分查找

二分查找 利用分治法,逐渐苏小查找范围,适用于有序数组. 时间复杂度是O(log2N). PS:二分查找算法的判定过程实际上可以借助一棵平衡二叉树来描述,中间位置的关键字可以看成二叉树的根节点. C++代码如下: 1 #include <iostream> 2 using namespace std; 3 template<class DataType> int binSearch(DataType key[],int n,DataType k) 4 { 5 int low=0,h

6-10 二分查找

6-10 二分查找(20 分) 本题要求实现二分查找算法. 函数接口定义: Position BinarySearch( List Tbl, ElementType K ); 其中List结构定义如下: typedef int Position; typedef struct LNode *List; struct LNode { ElementType Data[MAXSIZE]; Position Last; /* 保存线性表中最后一个元素的位置 */ }; Tbl是用户传入的一个线性表,其

分治法--二分查找、乘方、斐波那契数

1.二分查找 常见错误: 死循环:循环体外的初始化条件,与循环体内的迭代步骤, 都必须遵守一致的区间规则,也就是说,如果循环体初始化时,是以左闭右开区间为边界的,那么循环体内部的迭代也应该如此.如果两者不一致,会造成程序的错误. 溢出:middle = left + (right - left) / 2 终止条件:一般来说,如果左闭右闭,则left<=right: 如果一开一闭,则left<right: 关键看left能不能等于right,而且要考虑实际情况,有时不能这样简单终结,会出现死循环

Leetcode 240 Search a 2D Matrix II (二分法和分治法解决有序二维数组查找)

1.问题描述 写一个高效的算法,从一个m×n的整数矩阵中查找出给定的值,矩阵具有如下特点: 每一行从左到右递增. 每一列从上到下递增. 2. 方法与思路 2.1 二分查找法 根据矩阵的特征很容易想到二分法,但是这是一个二维的矩阵,如何将问题转化为一维是关键.实际上我们可以根据矩阵的第一列确定值可能所在的行的范围(limu,limd),其中limu=0,使得matrix[0][0]≤matrix[i][0]≤matrix[limd][0],i∈[0,limd].而确定limd的值可以使用二分法.

算法导论第2章 分治法与归并排序, 二分查找法

分治策略:将原问题划分成n个规模较小而结构与原问题相似的子问题,然后递归地解决这些子问题,最后再合并其结果,就可以得到原问题的解. 它需要三个步骤: 分解:将原问题分解成一系列的子问题. 解决:递归地解决各个子问题.若子问题足够小,则直接求解. 合并:将子问题的结果合并成原问题的解. 通过分治策略和分治步骤,可以简单地默出归并算法. 分解:将n个元素分成各自包含n/2个元素的子序列 解决:用归并排序法递归地对两个子序列进行排序. 合并:合并两个以排序的子序列,得到排序结果: void merge

LeetCode 240. 搜索二维矩阵 II (C#实现)——二分查找,分治法

问题:https://leetcode-cn.com/problems/search-a-2d-matrix-ii/ 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有矩阵 matrix 如下: [ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18,

算法学习一~分治法~二分查找,快速的找~

现在编程也算是走上门了,但是没有把算法掌握下来只能说自己还是门外汉,所以以后我们就开始努力的学习算法,现在把自己每天的学习分享在这里希望大家能喜欢,并且我也要在这里整理我一天的学习和思路,. 二分查找..大家经常需要在一个数组中寻找某个值.如果是一个已经拍好序的话那么可以很快的找到.我们考虑下暴力查找,就是a[n],中找一个m,那么最好时是o(1),最差时是0(n),最终平均情况就是长度n/2.这样的时间复杂度不算很高但是可以改进到logn的级别. 1 #include<stdio.h>//算

算法——基础篇——二分查找

     二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.     首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功

A - Superset CodeForces - 97B(人生第一个分治法,感觉,像二分啊。。)

/* 分治法,第一次做不是很懂,借鉴了神犇代码,但实操之后感觉像二分,,可能做得少了或者就是.... */ 题目大意: 一个集合里有若干点,要求你添加某些点后保证这个集合里的任意两点满足以下三个条件中至少一个: 1.在一个水平线上 2.在一个竖直线上 3.两点组成的矩形之间有点. 解题思路: 神犇所讲,将点排序,在中间点处建一条竖直线,令其余点在其上投影,二分. ps:不是很明白错误是什么,,结构体里重载<运算符可以,但是写个cmp函数就报错,不是很懂,贴上错误代码,如果神犇们知道什么错误,请评