快排+归并+整数二分

tips:

  1.注意边界处理,避免出现死循环

785. 快速排序

/*
eg:2
    1 2
用i则不能取到左边界,把x取值改成向上取整
用j则不能取到右边界,把x取值改成向下取整
取到边界会导致递归死循环
*/
#include<iostream>
#include<cstdio>
using namespace std;

const int N=1e6+10;

int n;
int q[N];

void quick_sort(int q[], int l, int r){
    if(l>=r) return;

    int x=q[l+r>>1],i=l-1,j=r+1;
    while(i < j){
        do i++; while(q[i]<x);
        do j--; while(q[j]>x);
        if(i<j) swap(q[i],q[j]);
    }

    //这里左半边排序不能改成我之前的模板(l,j-1),因为x的位置在每次拍完序后没有被固定
    quick_sort(q,l,j);////用i要保证不用到q的左边界,x取值那也要调整。
    quick_sort(q,j+1,r);
}

int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&q[i]);
    quick_sort(q,0,n-1);
    for(int i=0;i<n;i++) printf("%d ",q[i]);
    return 0;
}

快速排序模板

787. 归并排序

//AcWing 787. 归并排序
//实现思路,完善细节。
#include<cstdio>

using namespace std;

const int N=1e5+10;

int n;
int q[N],tmp[N];

void merge_sort(int q[],int l, int r){
    if(l>=r) return;

    int mid=l+r>>1;

    merge_sort(q,l,mid);
    merge_sort(q,mid+1,r);

    int i=l,j=mid+1;
    int k=0;
    while(i<=mid && j<=r){
        if(q[i]<=q[j]) tmp[k++]=q[i++];
        else tmp[k++]=q[j++];
    }
    while(i<=mid) tmp[k++]=q[i++];
    while(j<=r) tmp[k++]=q[j++];

    for(int i=l,j=0; i<=r; i++,j++) q[i]=tmp[j];

}
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&q[i]);

    merge_sort(q,0,n-1);

    for(int i=0; i<n; i++) printf("%d ",q[i]);
    return 0;
}

归并排序模板

789. 数的范围

//关键是定义性质,二分出这个性质的边界
//mid=(l+r+1)/2是因为向下取整,若l=r-1,则出现死循环
#include<iostream>
#include<cstdio>
using namespace std;

int n,m;
const int N=100010;
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<<r<<endl;
        }
    }
    return 0;
}

整数二分

原文地址:https://www.cnblogs.com/SUMaywlx/p/12301012.html

时间: 2024-11-08 22:58:33

快排+归并+整数二分的相关文章

字符串查找(二分和快排的运用)

Description 现在给你一个字典,再给出几个字符串,让你查找,这些字符串是否在其中. Input 第一行是两个整数M,N分别表示字典数和字符串数. 第2至第M+1行,每一行是一个字典. 第M+2至第M+2+N行是徐查找的字符串. (n<=10,0000, m<=20,0000, 字符串长度不超过10,且均为小写字母) Output 共N行,每行表示第i个字符串在不在字典中,用0表示不在,1表示在. Sample Input 5 3 acc cat multiply do will ac

排序(一)归并、快排、优先队列等

排序(一) 初级排序算法 选择排序 思想:首先,找到数组中最小的那个元素.其次,将它和数组的第一个元素交换位置.再次,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置.如此往复,直到将整个数组排序. [图例] 图中,x轴方向为数组的索引,y轴方向为待排序元素的值. 选择排序有两个很鲜明的特点: 运行时间和输入无关.为了找出最小的元素而扫描一遍数组并不能为下一遍扫描提供什么信息.这种性质在某些情况下是缺点.(无论数组的初始状态是什么,此算法效率都一样低效) 数据移动是最少的.每次交换都

算法总结——三大排序(快排,计数排序,归并)

快排: 适用条件:方便...只要数字不是很多 复杂度:O(nlogn)  每一层n复杂度,共logn层 原理:利用一个随机数与最后面一个数交换,那么这个随机数就到了最后一位,然后循环,如果前面的数大于最后一个数,那么把这个数放到前面去,经过一次排序之后,前面的数都是大于最后一个的,然后对1到k和k+1到n进行排序,一层一层地下去 模板: #include<cstdio> #include<algorithm> #include<time.h> using namespa

poj 2804 词典 (字典树 或者 快排+二分)

2804:词典 总时间限制:  3000ms  内存限制:  65536kB 描述 你旅游到了一个国外的城市.那里的人们说的外国语言你不能理解.不过幸运的是,你有一本词典可以帮助你. 输入 首先输入一个词典,词典中包含不超过100000个词条,每个词条占据一行.每一个词条包括一个英文单词和一个外语单词,两个单词之间用一个空格隔开.而且在词典中不会有某个外语单词出现超过两次.词典之后是一个空行,然后给出一个由外语单词组成的文档,文档不超过100000行,而且每行只包括一个外语单词.输入中出现单词只

hdu--4022--multimap&lt;别人用快排+二分,没学好&gt;

本来 我是想直接开2个计数数组 存下 行 列各自的元素个数的.. 可是 数据达到了 10^9 但是数据个数 只有10^5 虽然可以考虑用 离散化...但我想先map试下 毕竟 离散化烦~ 关于multimap的使用 和map还是有点差别的..但是 我们单纯地只是使用 stl中的函数的话 还是不存在什么难度吧 听说 <<STL源码剖析>>不错...可是 不太适合初学者~ =_=   大师 经典.. 我这题的wa错误 太难找了 厌死.... 我因为一开始想使用数组的原因  多此一举地

排序详解(希尔,快排,归并等)

今天集中把几种排序的方法列一下,当然最出名的希尔,快排,归并和其优化当然也是满载 说到希尔排序的话,不得不先提到的就是插入排序了,希尔排序就是对直接插入排序的一种优化,下面就是直接插入排序的思想 1 void InsertSort(int *a, size_t size) 2 { 3 assert(a); 4 for (int i = 1; i < size; ++i) 5 { 6 int index = i; 7 int tmp = a[index]; 8 int end = index -

常见经典排序算法学习总结,附算法原理及实现代码(插入、shell、冒泡、选择、归并、快排等)

博主在学习过程中深感基础的重要,经典排序算法是数据结构与算法学习过程中重要的一环,这里对笔试面试最常涉及到的7种排序算法(包括插入排序.希尔排序.选择排序.冒泡排序.快速排序.堆排序.归并排序)进行了详解.每一种算法都有基本介绍.算法原理分析.算法代码. 转载请注明出处:http://blog.csdn.net/lsh_2013/article/details/47280135 插入排序 1)算法简介 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过

三种排序:快排,归并,堆排

转自:http://www.cnblogs.com/LUO77/p/5798149.html (一)快排 快排考的是最多次的.之前看大神写的算法很简单,思想也很好.就一直用他的思想去思考快排了.挖坑法. 拿走第一个元素作为标兵元素,即挖坑,然后从后面找一个比它小的填坑,然后又形成一个坑,再从前面找一个比标兵大的填坑,又形成一个坑.……最后一个坑填入标兵就好. 然后就是递归了.再在标兵左边排序,右边排序. 1 void QSort(int* num, int start, int end) { 2

快排和归并分治总结

快排和归并排序都运用了分治的思想,所以在我看来这两种排序方法都有自己的相似性. 快排 在快排中,首先运用的是分割的方式,选取pivot,将比pivot小的元素放在pivot前面.将比pivot大的元素放在pivot后面. quickSort(arr[],low,high) { if(low<high) { pi = partition(arr,low,high); quickSort(arr,low,pi-1); quickSort(arr,pi+1,high); } } 接下来是实现这个方法的