UVa11401

11401 - Triangle Counting

Problem G Triangle Counting

Input: Standard Input

Output: Standard Output

 

 

You are given n rods of length 1, 2…, n. You have to pick any 3 of them & build a triangle. How many distinct triangles can you make? Note that, two triangles will be considered different if they have at least 1 pair of arms with different length.

Input

The input for each case will have only a single positive integer (3<=n<=1000000). The end of input will be indicated by a case with n<3. This case should not be processed.

Output

 

For each test case, print the number of distinct triangles you can make.

Sample Input                                                  Output for Sample Input

5

8

0

3

22


Problemsetter: Mohammad Mahmudur Rahman

  1 法一!!
  2 /*
  3 先打表!!!后推公式!!!
  4 
  5 i     3   4    5    6     7      8      9      10     11    12     13     14     15     16     17     18
  6  
  7 f[i]  0   1    3    7     13     22     34     50     70    95     125    161    203    252    308    372
  8 
  9 做差    1    2    4    6      9      12      16     20    25    30      36     42     49     56     64
 10 
 11 再做差    1    2    2     3      3       4       4      5     5     6        6      7      7     8
 12 
 13 在奇数项做差和偶数项做差即可!!!     
 14 */
 15 
 16 
 17 /*//一开始TLE!!后来就把它用来打表了,推出了通项公式!!!
 18 
 19 记得一道做过fft的题,打这个表轻轻松松!!!
 20 #include<stdio.h>
 21 #include<string.h>
 22 #include<algorithm>
 23 #include<math.h>
 24 #include<queue>
 25 #include<set>
 26 #include<vector>
 27 #include<bitset>
 28 using namespace std;
 29 typedef long long ll;
 30 
 31 const int M=1000010;
 32 ll s[M],f[M];
 33 int get(){
 34     char c;
 35     int res=0;
 36     while(c=getchar(),!isdigit(c));
 37     do{
 38         res=(res<<3)+(res<<1)+(c-'0');
 39     }while(c=getchar(),isdigit(c));
 40     return res;
 41 }
 42 
 43 */
 44 
 45 
 46 int main()
 47 {
 48     ll i,ans1,ans2,ans3,ans,n,m;
 49     while(~scanf("%lld",&n))
 50     {
 51         if(n<3)break;
 52         ll k=0;f[n+1]=n;
 53         while((++k)<=n)f[n+1-k]=f[n+1+k]=n-k;
 54         f[1]=f[0]=0;
 55         //for(i=0;i<=2*n;i++)printf("%lld**",f[i]);
 56         for(i=1;i<=n;i++)f[i*2]--;
 57         for(i=1;i<=2*n;i++)f[i]/=2;
 58         //for(i=0;i<=2*n;i++)printf("%lld**",f[i]);
 59         s[1]=0;
 60         ll ans=0;
 61         for(i=2;i<=2*n;i++)s[i]=s[i-1]+f[i];
 62         for(i=1;i<=n;i++)
 63         {
 64             ans+=s[2*n]-s[i];
 65             ans-=(i-1)*(n-i);
 66             ans-=(n-1);
 67             ans-=(n-i)*(n-i-1)/2;
 68         }
 69         printf("%lld**
",ans);
 70     }
 71     return 0;
 72 }
 73 
 74 
 75 
 76 
 77 
 78 
 79 #include<stdio.h>
 80 #include<string.h>
 81 #include<algorithm>
 82 #include<math.h>
 83 #include<queue>
 84 #include<set>
 85 #include<vector>
 86 #include<bitset>
 87 using namespace std;
 88 typedef long long ll;
 89 
 90 int main()
 91 {
 92     ll ans,k,n;
 93     while(1)
 94     {
 95         n=get();
 96         if(n<3)break;
 97         if(n%2==0){k=n/2-1;ans=k*(4*k*k+3*k-1)/6;printf("%lld
",ans);continue;}
 98         k=(n-1)/2-1;ans=k*(4*k*k+3*k-1)/6+(n/2-1)*(n/2);
 99         printf("%lld
",ans);
100     }
101     return 0;
102 }
103 
104 
105 
106 
107 
108 法2!!
109 
110 
111 
112 
113 
114 /*
115 递推:
116 设最大边为x的三角形有c[x]个,y+z>x;
117 
118 y的值  z的个数 
119 1       0
120 2       1
121 3       3
122 。。。。。
123 x-1     x-2
124 
125 
126 除去y=z的情况有(x-1)/2种!!
127 
128 剩下的再除以2即可!!
129 
130 C[x]= ((x-1)*(x-2)/2-(x-1)/2)/2;
131 
132 */ 
133 #include<stdio.h>
134 #include<string.h>
135 #include<algorithm>
136 #include<math.h>
137 #include<queue>
138 #include<set>
139 #include<vector>
140 #include<bitset>
141 using namespace std;
142 typedef long long ll;
143 
144 const int M=1000010;
145 ll f[M];
146 
147 int get(){
148     char c;
149     int res=0;
150     while(c=getchar(),!isdigit(c));
151     do{
152         res=(res<<3)+(res<<1)+(c-'0');
153     }while(c=getchar(),isdigit(c));
154     return res;
155 }
156 
157 
158 int main()
159 {
160     ll i;
161     int n;
162     f[3]=0;
163     for(i=4;i<M;i++)f[i]=f[i-1]+((i-1)*(i-2)/2-(i-1)/2)/2;
164     while(1)
165     {
166         n=get();
167         if(n<3)break;
168         printf("%lld
",f[n]);
169     }
170     return 0;
171 }
View Code
原文地址:https://www.cnblogs.com/skykill/p/3231210.html