ACM Arabella Collegiate Programming Contest 2015
有两种方法:
一:记录每个数出现的次数,然后从1~10000扫描如果i<32时,就是前32个出现的次数抽两个的意思,当i>32,就是加上本身的排列和i-32~i之间的数的抽取,说的我自己都不知道什么意思~~~
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
#define N 10010
int n,t,a[N],c[N];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int d;
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
scanf("%d",&d);
a[d]++;
}
int count=0;
for(int i=1;i<10001;i++)
c[i]=c[i-1]+a[i];
count+=c[32]*(c[32]-1)/2;
for(int i=33;i<10001;i++)
{
count+=(c[i-1]-c[i-32])*a[i]+a[i]*(a[i]-1)/2;
}
printf("%d\n",count);
}
return 0;
}
第二种方法:
想得有点久,当然我是看别人的。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 10010
#define inf 0x3f3f3f
int a[N];
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+n);
int c=0,j=0;
for(int i=1;i<n;i++) //主要代码
{
while(a[i]-a[j]>=32)
j++;
c+=i-j;
}
cout<<c<<endl;
}
return 0;
}
洗澡去了,,,,要断网了。。。