链接:https://ac.nowcoder.com/acm/contest/1069/H
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
64bit IO Format: %lld
题目描述
It's Halloween! Farmer John is taking the cows to a costume party, but unfortunately he only has one costume. The costume fits precisely two cows with a length of S (1 <= S <= 1,000,000). FJ has N cows (2 <= N <= 20,000) conveniently numbered 1..N; cow i has length Li (1 <= Li <= 1,000,000). Two cows can fit into the costume if the sum of their lengths is no greater than the length of the costume. FJ wants to know how many pairs of two distinct cows will fit into the costume.
输入描述:
* Line 1: Two space-separated integers: N and S
* Lines 2..N+1: Line i+1 contains a single integer: Li
输出描述:
* Line 1: A single integer representing the number of pairs of cows FJ can choose. Note that the order of the two cows does not matter.
示例1
输入
4 6 3 5 2 1
输出
4
说明
The four pairs are as follows: cow 1 and cow 3; cow 1 and cow 4; cow 2 and cow 4; and finally cow 3 and cow 4.
算法思想
采用哈希的办法先用计数数组把当前状态的分布情况存储下来
压缩状态从n^2到m
从上界的一半开始 往左边移动基准
对于每一个基准 i ,在 i ~ limit - i 范围内(除去当前的元素)的元素都可以与当前元素配对
每次可以匹配的元素个数用前缀和的形式不断更新
时间复杂度O(m)
1 #include <bits/stdc++.h> 2 #include <iostream> 3 #include <cstring> 4 #include <stack> 5 #include <cstdlib> 6 #include <queue> 7 #include <cmath> 8 #include <cstdio> 9 #include <algorithm> 10 #include <string> 11 #include <vector> 12 #include <list> 13 #include <iterator> 14 #include <set> 15 #include <map> 16 #include <utility> 17 #include <iomanip> 18 #include <ctime> 19 #include <sstream> 20 #include <bitset> 21 #include <deque> 22 #include <limits> 23 #include <numeric> 24 #include <functional> 25 26 #define gc getchar() 27 #define mem(a) memset(a,0,sizeof(a)) 28 #define mod 1000000007 29 #define sort(a,n,int) sort(a,a+n,less<int>()) 30 #define fread() freopen("in.in","r",stdin) 31 #define fwrite() freopen("out.out","w",stdout) 32 using namespace std; 33 34 typedef long long ll; 35 typedef char ch; 36 typedef double db; 37 38 const int maxn=1e5+10; 39 const double pi=acos(-1.0); 40 const int N=1e5+10; 41 42 43 ll l[1000005] = {0}; 44 int main() 45 { 46 ll n = 0 , s = 0 , L = 0; 47 cin >> n >> s; 48 for(int i = 1;i<=n;i++) 49 { 50 cin >> L; 51 l[L]++; 52 } 53 int counter = 0; 54 if(s % 2) 55 { 56 int right = 0; 57 for(ll i = s/2;i>=1;i--) 58 { 59 right += l[s-i] +l[i] -1; 60 counter += l[i] * right -l[i]*(l[i]-1)/2; 61 right += 1; 62 } 63 } 64 else 65 { 66 if(l[s/2] > 1) 67 counter += l[s/2]*(l[s/2]-1)/2; 68 int right = l[s/2]; 69 for(ll i = s/2-1;i>=1;i--) 70 { 71 right += l[s-i] +l[i] -1; 72 counter += l[i] * right -l[i]*(l[i]-1)/2; 73 //cout<<i<<' '<<right<<' '<<counter<<endl; 74 right += 1; 75 } 76 } 77 cout << counter << endl; 78 return 0; 79 }
队友用二分的做法 时间复杂度O(n*logn)
甚至很迷的是这道题暴力居然都过了 适当优化的暴力做法
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int N = 3e5; 8 int a[N], b[1000010] = {0}; 9 long long s[1000010]; 10 int main() 11 { 12 int n, k, m = 0; 13 cin>>n>>k; 14 for(int i = 0; i < n; i ++ ) { 15 scanf("%d", &a[i]); 16 m = max(m, a[i]); 17 b[a[i]]++; 18 }//读入 19 sort(a,a+n); 20 int half = k / 2; 21 int count = 0; 22 for(int i = 0; i < n; i ++ ) { 23 if(a[i] <= half) count ++; 24 else break; 25 } 26 long long ans = count * (count - 1) / 2; 27 s[0] = 0; 28 for(int i = 1; i <= k; i ++ ) s[i] = s[i - 1] + b[i]; 29 for(int i = 0; a[i] < half; i += b[a[i]] ){ 30 long long cnt = s[k - a[i]] - s[half]; 31 ans += cnt * b[a[i]]; 32 } 33 if(k%2 != 0) ans += b[half] * b[half + 1]; 34 //ans += b[half] * (b[half] - 1) / 2; 35 printf("%lld",ans); 36 return 0; 37 }