机试笔记6--查找
查找的问题一般可能会想到排序+二分查找,或者顺序查找,但是在机试中很容易出错,所以比较推荐用C++的map,虽然它实现的是哈希表的功能,但是它的实现确实红黑树,所以平均时间复杂度为nlogn
第一类查找问题即静态查找,有一组数据,在这数据中找某一个值,当然值不会简简单单的给个整数,他可能是个结构体。这类一般用map就可以解决
第二类则是动态查找,在查找的同时,还可能进行插入或者删除,这样的话排序+二分查找时间复杂度会变高,使用map依旧可以完成。
例题一
输入要求:
第一行输入一个正整数n(n < 100000)
第二行输入n个正整数,用空格隔开。
第三行输入一个正整数q(q<100000),表示查询次数。 接下来输入q行,每行一个正整数x,查询x是否存在。
输出要求:
如果x存在,请输出find,如果不存在,请输出no,并将x加入到集合中。
#include <bits/stdc++.h> using namespace std; int main() { int n; cin >> n; map<int,int> m; for(int i=0;i<n;i++){ int num; cin >> num; m[num]++;//可以看出map里的数初始都是零 } int q; cin >> q; for(int i=0;i<q;i++){ int key; cin >>key; if(m[key]!=0) cout << "find"<<endl; else{ cout << "no"<<endl; m[key]++; } } return 0; }
转换下思路,记录个数就可以解决了。
二分查找代码:
#include <bits/stdc++.h> using namespace std; int main() { vector<int> arr; int n; cin >> n;//构建查找数组 for(int i=0;i<n;i++){ int num; cin >> num; arr.push_back(num); } int key; cin >> key;//要查找的值 sort(arr,arr+n); int left = 0; int right = n-1; while(left<=right){ mid = left+(left+right)/2; if(arr[mid]<key) left = mid+1; else if(arr[mid]>key) left = right-1; else { cout<<"find"<<endl; return 0; } } cout <<"no find"<<endl; return 0; }
北京大学机试,查找学生信息,编号1177答案
#include <bits/stdc++.h> using namespace std; int main() { int N,M; map<int,int> m; map<int,int> f; while(cin>>N>>M){ for(int i=0;i<N;i++){ int num; cin >> num; m[i]=num; f[num]++; } for(int i=0;i<N;i++){ int key=m[i]; if(f[key]>1) cout << f[key]-1<<endl; else cout <<"BeiJu"<<endl; } m.clear(); f.clear(); } return 0; }
这里要注意,如果题目要求多组数据,一定要在每组完成后,清空你的数据结构!!!!