简单三角形计数数学题-hdu-4486-Pen Counts

来源:互联网 发布:mac系统打不开flash 编辑:程序博客网 时间:2024/05/16 00:37

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4486

题目意思:

给一个长度len,求把len分成三段凑成三角形的个数,如果是等腰三角形记1种,非等腰的记两种。

解题思路:

三角形计数。比赛的时候傻逼的用o(n^2)的暴力方法打表,虽然过了,不能更弱。。。-_- -_-  ! ==思路不行,马上转化,不要陷入死胡同。不受不正确思路影响。之前应该见过这样的计数的。。。。

分几种情况考虑:记三边为a<=b<=c

1、当n%3==0时,可能为等边三角形 +1

2、当a=b<c时,由a+b>c得2a>c  即2a>n-2a  得a>n/4   又由a<c得 a<n-2a 得a<n/3  综合得 n/4<a<n/3 对于每一个a总能构造一种。

3、当a<b=c时,由c>a得c>n-2c 即c>n/3   又b+c<n得 c<n/2  综合得 n/3<c<n/2 对于每一个c总能唯一构造一种。

4、当a<b<c时,枚举a(1~n/3) ,  由a<b<n-a-b 得b<(n-a)/2   由a+b>c   a+b>n-a-b  得b>(n-2a)/2   综合得  max(a,(n-2a)/2)<b<(n-a)/2   a、b确定了三角形也就唯一确定了。

代码:

#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#define eps 1e-6#define INF 0x1f1f1f1f#define PI acos(-1.0)#define ll __int64#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;/*freopen("data.in","r",stdin);freopen("data.out","w",stdout);*/int n;int up,dow;int uup(int x,int div) //返回<x/div的上届整数{   if(x%div==0)      return x/div-1;   return x/div;}int ddow(int x,int div)//返回>x/div的下届整数{   return x/div+1;}int main(){   int t,d;   scanf("%d",&t);   while(t--)   {      scanf("%d%d",&d,&n);      int ans=0;      if(n%3==0)         ans+=1; //当a=b=c时的情况      //printf("1:%d\n",ans);      up=uup(n,3);      dow=ddow(n,4);      if(up>=dow)         ans+=(up-dow+1); //当a=b<c时的情况     // printf("2:%d\n",ans);      up=uup(n,2);      dow=ddow(n,3);      if(up>=dow)      ans+=(up-dow+1); //当a<b=c时的情况     // printf("3:%d\n",ans);      for(int a=1;a<n/3;a++) //当a<b<c时的情况      {         dow=ddow(a,1);         int tmp=ddow(n-2*a,2);         up=uup(n-a,2);         dow=max(dow,tmp);         if(up>=dow)            ans+=(2*(up-dow+1));      }      printf("%d %d\n",d,ans);   }   return 0;}



原创粉丝点击