传送门:https://odzkskevi.qnssl.com/1110bec98ca57b5ce6aec79b210d2849?v=1492616502
题意:找到相差小于32的两个数,i<j,问有多少对,肯定有超市,所以要有优化方案。
二分:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=10000+5; int a[maxn]; int main() { //freopen("in.txt","r",stdin); int T; scanf("%d",&T); while(T--) { int n; int cnt=0; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); for(int i=0;i<n;i++) { int target=a[i]+32; if(a[n-1]<target) { cnt+=n-i-1; continue; } int left=i+1,right=n-1,mid; while(1) { mid=(left+right)/2; if(target>a[mid-1] && target<=a[mid]) break; if(a[mid]<target) left=mid+1; else right=mid; } cnt+=mid-i-1; } printf("%d ",cnt); } return 0; }
这个是其他人的思路,我觉得比较好,用到了点离散化的思想
#include <bits/stdc++.h> using namespace std; const int maxn = 10000+10; int v[maxn]; int s[maxn]; int q[maxn]; typedef long long LL; LL ans; int main() { // freopen("in.txt","r",stdin); int t,n,a,cnt; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i = 0; i<n; i++) { scanf("%d",&q[i]); } sort(q,q+n); cnt = 0; a = 0; for(int i = 0; i<n; i++) { if(q[i]!=a) { cnt++; v[cnt] = q[i]; s[cnt] = 1; a = q[i]; } else s[cnt]++; } ans = 0; for(int i = 1; i<cnt; i++)//与其他数 { for(int j = i+1; j<=cnt; j++) { if(abs(v[i]-v[j])<32) ans += s[i]*s[j]; else break;//因为已经排了序,如果与前面的差值都>=32, 那么与后面的差值就更大,直接退出即可。 } } for(int i = 1; i<=cnt; i++)//与相同的自己,i<j,2个则2*1/2=1,三个则3*2/2=3个,1个就没了 ans += s[i]*(s[i]-1)/2; printf("%lld ",ans); } return 0; }