传送门: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\n",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\n",ans);
}
return 0;
}