归纳:
用〈
a
〉表示最接近
a
的整数。
(
1
)
当
n
为偶数时,周长为整数
n
的三角形总数
S=
48
2
n
;
(
2
)
当
n
为奇数时,周长为整数
n
的三角形总数
S=
48
3
2
n
。
求的是排列数,讨论俩个相同的边*3,三个不同的*6.即可
#include<iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<cmath>
using namespace std;
long long sums=0;
void z1(int x,int y)
{
for(int i=1;i<x;i++)
{
if(i+x-i>y&&i+y>x-i&&x-i+y>i)
sums++;
}
for(int i=1;i<y;i++)
{
if(i+y-i>x&&i+x>y-i&&y-i+x>i)
sums++;
}
}
void z2(int x)
{
if(x%2==0)
{
//if(x<6)return ;
long long ss=0;
for(int i=1;i<x;i++)
{
if(i+i>x-i-i&&i+x-i-i>i)ss++;
}
long long ts=0;
double xx=(1.0*x*x)/48.0;
if(xx-(long long)xx>=0.5)ts=(long long)xx+1;
else ts=(long long)xx;
sums+=(ts-ss)*6;
if(x%3==0){sums+=1;ss--;}
ss=ss*3;
sums+=ss;
}
else
{
// if(x<5)return ;
long long ss=0;
long long ts=0;
for(int i=1;i<x;i++)
{
if(i+i>x-i-i&&i+x-i-i>i)ss++;
}
double xx=(x+3.0)*(3.0+x)/48.0;
if(xx-(long long)xx>=0.5)ts=(long long)xx+1;
else ts=(long long)xx;
sums+=(ts-ss)*6;
if(x%3==0){sums+=1;ss--;}
ss=ss*3;
sums+=ss;
}
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
int tx;
int ll=n,rr=0;
for(int i=0;i<m;i++)
{
scanf("%d",&tx);
if(tx<=ll)ll=tx;
if(tx>=rr)rr=tx;
}
int l=ll-1;int r=rr+1;
sums=0;
if(l>=1&&r<=n)
{
z1(l,n-r+1);
}
else
{
if(l<1&&r<=n)
{
z2(n-r+1);
}
else if(r>n&&l>=1)
{
z2(l);
}
}
printf("%I64d\n",sums);
}
return 0;
}
原文:http://blog.csdn.net/u011498819/article/details/44999721