zoukankan      html  css  js  c++  java
  • hdu-4466-Triangle 数学题

    题目链接:

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

    题目意思:

    一根长为N的木棒,长度分成若干个三角形,使得任意两个三角形都相似。对应顺序三角形全部全等的为同一种分法,求总共有多少种分法。

    解题思路:

    数学题。

    先考虑分成一个三角形的情况。

    不妨设a<=b<=c;

    1、当b=c时,a至少为1,所以c<=(n-1)/2

    而a<=b 所以n-2*c<=c =>c>=n/3; 故共有(n-1)/2-(n/3)+(n/3?0:1)种。

    2、当b<c时,肯定有b<=c-1 

    此时若a+b>c 则a+b>c-1 

    如果a,b,c能构成三角形,则a,b,c-1也一定能够构成三角形。

    反过来,如果a,b,c-1能够构成三角形,也即a+b>c-1 当a+b!=c时,一定能使a,b,c构成三角形。故可以通过dp[n-1]递推过来,然后减去a+b=c+1的情况。

    此时n=2*c+1,c=(n-1)/2  只有当n为奇数的时候才有可能,而a+b=(n-(n-1)/2),a<=b 所以这种情况共有 (n-(n-1)/2)/2种,化简得(n+1)/4


    在考虑有多个三角形的情况。

    假设N=a*b 则把b作为一个基本三角形,a个1,作为a个部分,中间有a-1个隔板,每个隔板可选可不选,一共有2^(a-1)种情况。

    当所有的隔板都不选的话,就是一个大三角形,所以此时要把,刚才求得的一个三角形中三边不互质的数量减掉。而每个约数,对应的该约数能拆分成一个互质三角形的种数的不互质的三角形,乘以倍数就是大的不互质的三角形。


    详见代码:

    #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;
    #define M 1000000007
    #define N (5000000+10)
    
    /*
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    */
    int dp[N],bin[N]; //dp[i]表示一个三角形的情况,并且是互质的情况
    
    void init()
    {
       dp[3]=1;
       for(int i=4;i<N;i++)
       {
          dp[i]=dp[i-1]+(i-1)/2-i/3+(i%3?0:1); //b==c的情况
          if(!(i&1)) //当前一个为奇数
             dp[i]-=i/4; //减去,递推中不满足要求的部分
          dp[i]=dp[i]%M;
          if(dp[i]<0)
             dp[i]+=M;
       }
       bin[1]=1;
       for(int i=2;i<N;i++)
       {
          bin[i]=(bin[i-1]<<1)%M;
          for(int j=2;i*j<N;j++)
          {
             dp[i*j]-=dp[i]; //减去一个三角形中三边不互质的部分,,
             if(dp[i*j]<0)   //也就是对应的约数的dp[i],对于每个互质的小的a,b,c 对应一个j*a,j*b,j*c
                dp[i*j]+=M;
          }
       }
       return ;
    }
    
    int main()
    {
       int n,ca=0;
    
       init();
       //printf("%I64d
    ",dp[3]);
    
       while(scanf("%d",&n)!=EOF)
       {
          int ans=0;
          for(int i=1;i*i<=n;i++)
          {
             if(n%i)
                continue;
             ans=(ans+1LL*dp[i]*bin[n/i])%M; //中间乘法可能会溢int
             if(i*i!=n)
                ans=(ans+1LL*dp[n/i]*bin[i])%M;
          }
          printf("Case %d: %I64d
    ",++ca,ans);
       }
       return 0;
    }
    
    


  • 相关阅读:
    C#.NET中现在用的SqlHelper操作方法集合【收藏版】
    SQLHelper.cs的经典代码收集
    ASP.NET数据格式的Format DataFormatString
    asp.net操作 httpcookie
    项目开发中我所用到的SQL收集
    GridView的dataformatstring设置
    jQuery事件处理: 别再乱用“return false”了
    非常不错的空白占位符“    ”
    Hello World
    VSFlexGrid 控件属性方法一览
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3212304.html
Copyright © 2011-2022 走看看