http://acm.sjtu.edu.cn/OnlineJudge/problem/1382
注意到 排序之后 i从前向后扫描时,cur恰好是从后向前的,所以即使是双重循环,也是O(n)的算法。
#include <iostream> #include <algorithm> using namespace std; int N,S; unsigned int l[100000+5]={0}; //记录每包的数目 bool cmp_int(const int& a, const int& b){ return a<b; } int main(int argc, char const *argv[]) { cin>>N>>S; //输入 for (int i = 1; i <= N; ++i) cin>>l[i]; unsigned long long ans = 0; //排序 sort(l+1,l+N+1,cmp_int); int cur=N; //i从前向后 cur从后向前 双向扫描 for (int i = 1; i <= N; ++i) { for(;cur>=1;cur--){ if(l[cur]+l[i] <= S) //直到找到刚好可以装入的cur break; } if(cur<i) break; //下标相减 ans += cur - i; } cout<<ans<<endl; return 0; }