Uva 10474 sort以及lower_bound的用法

Posted 努力的程序媛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Uva 10474 sort以及lower_bound的用法相关的知识,希望对你有一定的参考价值。

现有N个大理石,每个大理石上写了一个非负整数。首先把各数从小到大排序,然后回 答Q个问题。每个问题问是否有一个大理石写着某个整数x,如果是,还要回答哪个大理石上 写着x。排序后的大理石从左到右编号为1~N。(在样例中,为了节约篇幅,所有大理石上 的数合并到一行,所有问题也合并到一行。)
样例输入:
4 1          (N Q)
2 3 5 1    (石头)
5             (问题)
5 2
1 3 3 3 1
2 3
样例输出:
CASE #1:
5 found at 4
CASE #2:
2 not found
3 found at 3

 

#include<iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
    int N, Q;
    while (scanf("%d%d", &N, &Q) == 2)
    {
        int *a = new int[N];
        int *b = new int[Q];
        for(int i=0;i<N;i++)
            scanf("%d", &a[i]);
        for(int j=0;j<Q;j++)
            scanf("%d", &b[j]);
        sort(a, a + N);
        bool flag=false;
        for (int k = 0; k < Q; k++)
        {
            for (int l = 0; l < N; l++)
                if (b[k] == a[l]) { flag = true; printf("%d found at %d\n", b[k], l + 1); break; }
            if (flag != true) { printf("%d not found\n", b[k]); }
        }
        delete[]a;
        delete[]b;
        a = NULL;
        b = NULL;
    }
}

很基础的排序和查找,然而自己却卡在while上一会,不心细果然什么都办不了

用stl会快很多

#include<cstdio> 
#include<algorithm> 
using namespace std; 
const int maxn = 10000;
int main() 
{
    int n, q, x, a[maxn], kase = 0; 
    while (scanf("%d%d", &n, &q) == 2 && n) 
    {
        printf("CASE# %d:\n", ++kase);
        for (int i = 0; i < n; i++) scanf("%d", &a[i]);
        sort(a, a + n); //排序
        while(q--)
        {     
            scanf("%d", &x);
            int p = lower_bound(a, a+n, x) - a; //在已排序数组a中寻找x
            if(a[p] == x) printf("%d found at %d\n", x, p+1);
            else printf("%d not found\n", x);
        }  
    }  
    return 0; 
}

sort

排序,并非只是普通的快速排序,除了对普通的快速排序进行优化,它还结合了插入排序堆排序。根据不同的数量级别以及不同情况,能自动选用合适的排序方法。当数据量较大时采用快速排序,分段递归。一旦分段后的数据量小于某个阀值,为避免递归调用带来过大的额外负荷,便会改用插入排序。而如果递归层次过深,有出现最坏情况的倾向,还会改用堆排序。

#include <algorithm>
 
template< class RandomIt >
void sort( RandomIt first, RandomIt last );
 
template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );

cmp的用法自行定义

例如:

#include<iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
using namespace std;
struct Node {
    int x, y;
}p[1001];
int n;
int cmp(Node a, Node b) {
    if (a.x != b.x) return a.x < b.x;  //如果a.x不等于b.x,就按x从小到大排
    return a.y < b.y;  //如果x相等按y从小到大排
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d%d", &p[i].x, &p[i].y);
    sort(p + 1, p + n + 1, cmp);
    for (int i = 1; i <= n; i++) printf("%d %d\n", p[i].x, p[i].y);
    return 0;
}
lower_bound
查找一个比自己大或者和自己相等的数并返回它的位置
注意:调用lower_bound之前必须确定序列为有序序列,否则调用出错。
template<class ForwardIterator, class Type>
   ForwardIterator lower_bound(
      ForwardIterator _First, 
      ForwardIterator _Last,
      const Type& _Val
   );
template<class ForwardIterator, class Type, class BinaryPredicate>
   ForwardIterator lower_bound(
      ForwardIterator _First, 
      ForwardIterator _Last,
      const Type& _Val,
      BinaryPredicate _Comp
   );
传入参数说明:

_First 要查找区间的起始位置

_Last 要查找区间的结束位置

_Val 给定用来查找的值

_Comp 自定义的表示小于关系的函数对象,根据某个元素是否满足小于关系而返回true或者false
 

 

lower_bound(first,last,val)表示找到第一个>=val的值的地址 
upper_bound(first,last,val)表示找到第一个>val的值的地址

在lower_bound(first,last,val,cmp)中cmp是比较函数

在lower_bound(first,last,val)中cmp默认为

bool cmp(mid,val){
    return mid<val;//表示如果mid<val 则继续lower_bound

 

所以当mid>=val时停止 

以上是关于Uva 10474 sort以及lower_bound的用法的主要内容,如果未能解决你的问题,请参考以下文章

D - Where is the Marble? (UVA - 10474)

Uva10474

UVA 10474

UVa10474

大理石在哪儿(UVa10474)

UVA 10474 Where is the Marble