题目链接:https://odzkskevi.qnssl.com/1110bec98ca57b5ce6aec79b210d2849?v=1490453767
题解:
这种方法大概跟离散化扯上点关系:首先直接用数组去接这组输入,然后对数组进行排序。之后把相等的数并在一起,并统计他们的个数,这样就重新得到两个数组,一个记录数字val,另一个记录个数sum。然后计算就可以了。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<queue> #include<vector> #include<algorithm> #include<map> #include<string> #include<set> #define LL long long #define MAX(a,b) (a>b?a:b) #define MIN(a,b) (a<b?a:b) using namespace std; int v[100000]; int s[100000]; int q[100000]; LL ans; int main() { 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++)//与自己 ans += s[i]*(s[i]-1)/2; printf("%lld ",ans); } return 0; }