ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443
出自蓝桥学苑 GtDzx老师
#枚举与优化套路(1)
这里有一些非常常用的思路。1是二分,二分查找、二分搜索非常有效,一般是复杂度从O(N)降到O(logN)。使用范围也很广,我们会在后面专门拿出一节时间来讲。2是用Hash,空间换时间。此外还有一些常用的套路:比如双指针,Leetcode上对应的分类是two pointer,直译过来就是双指针,大概的思想就是滑动窗口。还比如前缀后缀和,也是空间换时间的思路
#枚举与优化套路(2)
使用map(红黑树)或者unoreder_map(哈希表),c++11支持,时间复杂度为O(logn)和O(1)
#枚举与优化套路(3)
使用map(红黑树)或者unoreder_map(哈希表),c++11支持,时间复杂度为O(logn)和O(1)
支持C++11
不支持C++11
#include <iostream>
#include <set>
using namespace std;
int n, k, x, ans = 0;
set<int> myset;
int main(){
cin >> n >> k;
for(int i=0; i<n; i++){
cin >> x;
myset.insert(x);
}
for(set<int>::iterator i=myset.begin(); i!=myset.end(); i++){
if(myset.find((*i)+k) != myset.end()){ // (*)解引用
ans++;
}
}
cout << ans << endl;
return 0;
}
支持C++11
不支持C++11
#include <iostream>
#include <map>
using namespace std;
int n, c, t, st;
map<int, int> cnt;
int main(){
cin >> n;
for(int i=0; i<n; i++){
cin >> c;
st = 0;
for(int j=0; j<c; j++){
cin >> t;
st += t;
if(j != c-1) cnt[st]++;
}
}
int max = 0;
for(map<int,int>::iterator item=cnt.begin(); item!=cnt.end(); item++){
if((*item).second > max) max = (*item).second;
}
cout << n-max << endl;
return 0;
}
#枚举与优化套路(4)
例题:蓝桥杯:四平方和、hihoCoder #1505题:小Hi和小Ho的礼物。
不支持C++11
#include <iostream>
#include <map>
#include <cmath>
using namespace std;
int n;
map<int, int> f;
int main(){
cin >> n;
for(int c=0; c*c <= n/2; c++){
for(int d=c; c*c+d*d<=n; d++){
if(f.find(c*c + d*d) == f.end()){
f[c*c+d*d] = c; // 保存最小的c
}
}
}
for(int a=0; a*a*4<=n; a++){
for(int b=a; a*a+b*b<=n/2; b++){
if(f.find(n-a*a-b*b) != f.end()){ // 找到最小的b
int c = f[n-a*a-b*b];
int d = int(sqrt(n - a*a - b*b - c*c) + 1e-3);
cout << a << ' ' << b << ' ' << c << ' ' << d << endl;
return 0;
}
}
}
return 0;
}
有些同学可能会有疑问,就是f里保存的是c最小的解,会不会这个c比b小,不满足题目要求。比如N=30,我们枚举到a=1,b=2,这时f[25]=0,我们找到的解会是a=1, b=2, c=0, d=5。实际上不用担心这个问题。因为如果a=1, b=2, c=0, d=5是一个解,那么换一下顺序a=0, b=1, c=2, d=5也一定是一个解。并且a=0, b=