归纳:
用〈
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