现在来找找AC方式,首先,剖析题目,列出条件:Xa<Xb<Xc<Xd,Xb-Xa=2(Xd-Xc),Xb-Xa<Xc-Xb/3
遇到这种有条件的题,通常把图形画出来比较直观。

如图所示,若把d点确定,设c-d距离为i,则a,b的距离就是2i,则b,c的距离>2*(a-b)也就是>6i,总距离大于9i,那么我们的外层循环就枚举i,再枚举d的位置,d的方案数就等于(前面所有a的方案)*(前面所有b的方案)*(当前c的方案数),c的方案数=(前面所有a的方案)*(前面所有b的方案)*(当前d的方案数),同理,枚举a的位置,也可以得到a与b的方案数。
当然,说了这么多估计你也可能是懵逼的,看看代码再结合一下分析吧。
- #include<cstdio>
- #define M 15005
- int a[M],b[M],c[M],d[M],w[3*M],h[3*M];
- int n,m,i,j,x,s;
- int main()
- {
- scanf("%d%d",&n,&m);
- for(i=1;i<=m;i++)
- {
- scanf("%d",&h[i]);
- w[h[i]]++;
- }
- for(i=1;9*i<n;i++)
- {
- x=9*i+1;s=0;
- for(j=9*i+2;j<=n;j++)
- {
- s+=w[j-x]*w[j-x+2*i];
- d[j]+=s*w[j-i];
- c[j-i]+=s*w[j];
- }
- s=0;
- for(j=n-x;j>=1;j--)
- {
- s+=w[j+x]*w[j+x-i];
- a[j]+=s*w[j+2*i];
- b[j+2*i]+=s*w[j];
- }
- }
- for(i=1;i<=m;i++)
- printf("%d %d %d %d\n",a[h[i]],b[h[i]],c[h[i]],d[h[i]]);
- }