紫书—关于例题5-1大理石在哪的思考
题目链接:https://vjudge.net/problem/UVA-10474
解题的主要思路:先用vector存放数据,然后用sort来排序,再用lower_bound()(二分查找)查找数据,思想很简单,但仍有一些细节需要处理.
AC代码展示:
#include<bits/stdc++.h> using namespace std; int n,m; vector<int>num; //存放大理石的数据的动态数组 vector<int>ans; //存放二分查找的结果的动态数组 vector<int>question; //存放待查找的数据的动态数组 int main(){ int flag=0; while(scanf("%d%d",&n,&m),m!=0||n!=0){ flag++; num.clear(); ans.clear(); question.clear(); //存放大理石的数据的数组 for(int i=0;i<n;i++){ int a; scanf("%d",&a); num.push_back(a); } sort(num.begin(),num.end()); //begin()返回的是第一个元素的迭代器,但是end()返回的却是末尾元素再下一个元素的迭代器 for(int i=0;i<m;i++){ int b; scanf("%d",&b); question.push_back(b); //注意这里通过lower_bound()判断数组中是否有查找的数据的方法 if(num[lower_bound(num.begin(),num.end(),b)-num.begin()]==b&&((lower_bound(num.begin(),num.end(),b)-num.begin())<num.size())){ //lower_bound()若没找到则返回end(),为了防止莫名奇妙多出一个相同的数据,这是要判断返回值是否超出数组边界 cout<<lower_bound(num.begin(),num.end(),b)-num.begin()<<endl; ans.push_back(lower_bound(num.begin(),num.end(),b)-num.begin()+1); //注意这里输出要+1 }else{ ans.push_back(-1); } } cout<<"CASE# "<<flag<<':'<<endl; //结果输出 for(int i=0;i<ans.size();i++){ if(ans[i]!=-1){ cout<<question[i]<<' '<<"found at "<<ans[i]<<endl; }else if(ans[i]==-1){ cout<<question[i]<<' '<<"not found"<<endl; } } } }
注意事项:1.利用迭代器对数组进行排序: sort(a.begin(),a.end()) or sort(a,a+a.size()) ,因为sort排序的范围为[a.begin(),b.end())左开右闭。 2.lower_bound(a.begin(),a.end(),value)的作用是在[a.begin(),a.end())的范围内搜索第一个>=value的值,若找到则返回该值对应的迭代器,若没有找到则返回a.end().因此为了防止莫名多出个数据,应该多 加一个if判断返回的迭代器是否已经超出最后一个数据.
3.可以利用 lower_bound(a.begin(),a.end(),value)-a.begin()来得到value的下标,同时利用该性质判断该数组是否含有value.
4.ans数组记得要+1,因为答案要求从1开始,而原先用lower_bound函数的方法是从0开始.
5.begin()返回的是第一个元素的迭代器,但是end()返回的却是末尾元素再下一个元素的迭代器.

浙公网安备 33010602011771号