一.STL
1.hypot() 求两点间的距离 谨慎使用 太耗时了
用法: res=min(res,hypot(nums[i].x-nums[j].x,nums[i].y-nums[j].y));//太耗时了 不如自己写
2.back() 求vector数组的最后一个元素 若为二维的vector则该元素为 一维数组 back()[1] 表示一维数组的第二个元素
优先队列pq用方法:emplace表示入队一个元素 ,pop()表示删除队头元素,top()表示获取队头元素
vector用方法emplace_back:表示从最后添加一个元素 back()表示获取最后一个元素 pop_back()表示删除最后一个元素
用法:(res.back()[1]>=intervals[i][0])
3.max_element(vector.begin(),vector.end()) 求vector数组的最大元素 注意要加 不然求的是地址
4.accumulate() 求和函数
用法:accumulate(vector.begin(),vector.end(),0) 这个0表示 初始sum设为0
5.lower_bound:返回大于等于目标值的迭代器
例一:
#include
#include
#include
using namespace std;
int main()
{
vector v = { 3, 4, 1, 2, 8 };
// 无序数组,不用sort排序,下面调用lower_bound排序
// 定义两个迭代器变量
vector::iterator iter1;
vector::iterator iter2;
//less() 是建小堆,排升序。
//所以数组 v = {1,2,3,4,8}
//我们找第一个比1大的,那肯定就是首元素1了
//我们找第一个比8大的,没有,所以就指向数组最后一个元素8了
iter1 = lower_bound(v.begin(), v.end(), 1, less());//
iter2 = lower_bound(v.begin(), v.end(), 8, less());//
cout << iter1 - v.begin() << endl; //下标 所以就是 0
cout << iter2 - v.begin() << endl; //下标 所以就是 4
system(“pause”);
}
例二:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
vector<int> v = { 3, 4, 1, 2, 8 };
// 无序数组,不用sort排序,下面调用lower_bound排序
// 定义两个迭代器变量
vector<int>::iterator iter1;
vector<int>::iterator iter2;
//less<int>() 是建小堆,排升序。
//所以数组 v = {1,2,3,4,8}
//我们找第一个比1大的,那肯定就是首元素1了
//我们找第一个比8大的,没有,所以就指向数组最后一个元素8了
iter1 = lower_bound(v.begin(), v.end(), 1, less<int>());//
iter2 = lower_bound(v.begin(), v.end(), 8, less<int>());//
cout << iter1 - v.begin() << endl; //下标 所以就是 0
cout << iter2 - v.begin() << endl; //下标 所以就是 4
system("pause");
}
二.注意事项
1.自己最好手写两点间的距离函数
如:double dis(Node &a,Node &b){
return (a.x-b.x)(a.x-b.x)+(a.y-b.y)(a.y-b.y);//在结果加sqrt 可以节约时间
}
注意:在最后的结果才加sqrt可以节约时间
2.下面语句可以四舍五入到保留指定位数
cout<<fixed<<setprecision(4)<<sqrt(solution.minDistance(nums))<<endl;
3.以下两个for循环 是求最近点对的关键 确保每个点都与其他点参与了一次运算 而没有重复计算
for(int i=0;i<nums.size();i++){
for(int j=i+1;j<nums.size();j++){
res=min(res,dis(nums[i],nums[j]));
}
}
4.对于二维数组的遍历 最好使用for(int num:nums)这种形式 更加方便
如
for(vector<int> update:updates){
int i=update[0];
int j=update[1];
int val=update[2];
difference.increment(i,j,val);
}
5.二维坐标 (x,y) 可以转换成 x * n + y 这个数(m 是棋盘的行数,n 是棋盘的列数),这是将二维坐标映射到一维的常用技巧。
如二维数组 投影到一维数组后 就为:{0,1,2,3}
x 0 | x 1 |
---|---|
x 2 | x 3 |
6.在克鲁斯卡尔问题 求最小生成树中 当题中给出的点为 坐标形式(x,y) 没有显示的给出两个点的权重
则我们可以开一个数组 用于放 两个点的信息以及权重 这一步很精妙 如下:
vector<vector<int>> edges;
UF uf(m);
int mst=0;
for(int i=0;i<m;i++){
for(int j=i+1;j<m;j++){
int x1=points[i][0],x2=points[i][1];
int y1=points[j][0],y2=points[j][1];
//这一步太秀了 好好琢磨
edges.push_back({i,j,abs(x1-x2)+abs(y1-y2)});
}
}
这个 edge数组 就代替了 原题中给出的数组 因为这个数组是标准的三元组 满足我们求最小生成树的需要。
7.关于emplace函数 在vector数组 是这样用的emplace(pos,value) 即必须给出在哪个位置插入元素
而在优先队列priority_queue中 emplace没有pos参数 只有value一个参数
但两者的emplace_back函数是一样的形式
- vector<vector> nums(m, vector(2));这样定义二维数组 表示 你要用到nums[i][j],不可以 nums[x].emplace_back(y);
而vector<vector> nums(1000); 这样定义的话 类似 图的邻接表 你会这样操作 nums[x].emplace_back(y);也可以nums[i][j]