大理石在哪儿(Where is the Marble?,Uva 10474)
现有N个大理石,每个大理石上写了一个非负整数。首先把各数从小到大排序,然后回 答Q个问题。每个问题问是否有一个大理石写着某个整数x,如果是,还要回答哪个大理石上 写着x。排序后的大理石从左到右编号为1~N。(在样例中,为了节约篇幅,所有大理石上 的数合并到一行,所有问题也合并到一行。)
样例输入:
4 1
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
【分析】
题目意思已经很清楚了:先排序,再查找。使用algorithm头文件中的sort和lower_bound 很容易完成这两项操作,代码如下:
#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; }
lower_bound 函数:
lower_bound()返回值是一个迭代器,返回指向比key大的第一个值的位置。例如:
#include <algorithm> #include <iostream> using namespace std; int main() { int a[]={1,2,3,4,5,7,8,9}; printf("%d",lower_bound(a,a+8,6)-a); return 0; }
lower_bound函数返回的是一个地址,-a之后变成下标。
不用lower_bound函数:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int main() { int n,m,count=0; while(1){ cin>>n>>m; if(n==0) break; int a[n]; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } printf("CASE# %d:\n",++count); sort(a+1,a+n+1); while(m--){ int x; scanf("%d",&x); int flag=0; for(int i=1;i<=n;i++){ if(x==a[i]){ printf("%d found at %d\n",x,i); flag=1; break; } } if(!flag) printf("%d not found\n",x); } } return 0; }