题目
1. 思路
用数组(或者vector)收集各个大理石写着的数字元素,先从小到大排序,然后查找指定数字所在位置。
sort(v.begin(),v.end())
:从小到大排序;
lower_bound
:查找“大于或等于x的第一个位置”
2. 解决方案
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=10000;
int main(){
//n:石头个数 q: 问题个数 x: a[maxn]:石头数组
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); //排序 :a是数组,返回数组首地址 sort(v.begin(),v.end()) 从小到大排序
while(q--){
scanf("%d",&x);//输入寻找的x
int p=lower_bound(a,a+n,x)-a; //找x,大于或等于x的第一个位置
if(a[p]==x){
printf("%d found at %d\n",x,p+1);
}else {
printf("%d not found\n",x);
}
}
}
return 0;
}
运行结果:
石头个数:4;问题个数:2;石头数组:5,2,3,1;先给数组排序,结果为:1,2,3,5;问题1:找x=2;问题2:找x=4.
3. 总结与反思
while(scanf("%d%d",&n,&m)==2&&n&&m)
的含义:
第一个数输入的返回值为两个%d, 意思为只有输出两个整数后才返回2。所以 scanf() == 2;&& 的意思为: 不但要输入2个整数int类型的数,还有n且m不等于0。
意义:无限循环执行while循环。lower_bound(begin,end,x)
:
lower_bound( )和upper_bound( )都是利用二分查找
的方法在一个排好序的数组中进行查找的。
- 从小到大排序:
lower_bound(begin,end,num )
:从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num)
:从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。 - 从大到小排序:
lower_bound( begin,end,num,greater<type>() )
:从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num,greater<type>() )
:从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
sort(v.begin(),v.end())
从小到大排序。可以给任意对象排序,包括内置类型、自定义类型。