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?n?(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
解題思路,分段法,f [n] 記錄最長的那條邊不超過n的放法數, 假設c[n] 為最長邊為n的放法數 ?f [n] = f [n-1] + c[n] 。
假設最長邊為z,其它為 x,y;
則 ? z-x < y < z
當 ?x=1 時, z-1<y<z ?0 種方案,
當 ?x=2 時, z-2<y<z ?1 種方案,
......................................................
當 ?x=z-1時, 1<y<z ?z-2種方案
所以總計 (z-1)*(z-2)/2 種方案
但是其中包含了x與y想等的情況,因為 x取值為 [ z/2+1 , z-1 ] 區間內可能 x,y相等,共 (z-1)- (z/2+1)+1=z/2-1 種方案
而且x,y與 y,x認為為兩個,重復計算了,所以除以2
所以 c[n]= [?(z-1)*(z-2)/2 -(z/2-1) ] / 2
#include <iostream>
using namespace std;const int maxn=1000000;
unsigned long long f[maxn+10];
int n;void ini(){f[3]=0;for(long long z=4;z<=maxn;z++){f[z]=f[z-1] + ( (z-1)*(z-2)/2 - (z/2 -1) )/2;}
}int main(){ini();while(cin>>n && n>=3){cout<<f[n]<<endl;}return 0;
}