Description
给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个正方形。注意木棍不能弯折。问方案数。
正方形:四条边都相等、四个角都是直角的四边形。
Input
第一行一个整数n。
第二行包含n 个整数ai,代表每根木棍的长度。
8
4 5 1 5 1 9 4 5
Output
一行一个整数,代表方案数。
3
桶预处理+n^2实现
分类讨论
2 2 1 1 和 3 1 1 1 (数字表示每条边要用到的木棍数)
首先,1即边长是一定要枚举的
2 2 1 1:
2的话我们可以分四种情况讨论:(枚举a)
1:a+a a+a
直接判a*2时候等于边长然后做就可以了
2:a+a b+c
这儿就要用到f数组了(f[i]表示两个木棒组成的长度为i的方案数)
因为f[i]还包含了a+a的情况,所以减去即可
3:a+b a+b
有了a,便可以得到b了
然后判断一下a,b是否都有两个以上
有的话便加到答案里。
4:a+b c+d
这个嘛,就又要用到f数组了
f[边长]记得减去a+b的方案数即可
对了,还有减去c=d的情况哦,哦,哦
3 1 1 1:
3的话我们就不用分情况了
先枚举其中的一条边,然后用f数组得出另外两条的方案数即可
还要减去两个相等的情况
记得特判三个都相等的情况
下面贴代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,a[5010],b[5010][2],tot=1,cnt=0;
int c[10000001],d[20000001];
ll ans=0,s,ww;
inline int read()
{
int x=0; char c=getchar();
while (c<'0' || c>'9') c=getchar();
while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x;
}
int main()
{
freopen("yist.in","r",stdin);
freopen("yist.out","w",stdout);
n=read();
for (int i=1;i<=n;i++)
{
a[i]=read();c[a[i]]++;
for (int j=1;j<i;j++) d[a[i]+a[j]]++;
}
sort(a+1,a+n+1);
b[tot][0]=a[1],b[tot][1]=1;
for (int i=2;i<=n;i++)
{
if (a[i]==a[i-1]) b[tot][1]++;
else b[++tot][0]=a[i],b[tot][1]=1;
}
for (int i=1,k;i<=tot;i++)
{
if (b[i][1]>=2) // 2 2 1 1
{
s=0;k=0;ww=b[i][1]*(b[i][1]-1)>>1;
if (b[i][0]%2==0) k=(c[b[i][0]>>1])*(c[b[i][0]>>1]-1)>>1;
for (int j=1;(b[j][0]<<1)<=b[i][0];j++)
if ((b[j][0]<<1)==b[i][0])
{
//a a & a a
if (b[j][1]>=4) ans+=ww*b[j][1]*(b[j][1]-1)*(b[j][1]-2)*(b[j][1]-3)/24;
//a a & b c
if (b[j][1]>=2) ans+=ww*b[j][1]*(b[j][1]-1)*(d[b[i][0]]-(b[j][1]*(b[j][1]-1)>>1))>>1;
}
else
{
int mid=c[b[i][0]-b[j][0]];
//a b & a b
if (b[j][1]>=2 && mid>=2)
ans+=ww*b[j][1]*(b[j][1]-1)*mid*(mid-1)>>2;
//a b & c d
s+=ww*b[j][1]*mid*(d[b[i][0]]-b[j][1]*mid-k);
}
ans+=(s>>1);
}
if (b[i][1]>=3) // 3 1 1 1
{
s=0;ww=b[i][1]*(b[i][1]-1)*(b[i][1]-2)/6;
for (int j=1;a[j]<b[i][0];j++)
{
int mid=b[i][0]-a[j];
//a a a
if (a[j]*3==b[i][0]) s+=ww*(d[mid]-c[mid-a[j]]+1);
else if (mid>a[j]) s+=ww*(d[mid]-c[mid-a[j]]);
else s+=ww*d[mid];
}
ans+=s/3;
}
}
printf("%lld
",ans);
return 0;
}