uva 11401
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 |
题目描述:
有多少种方法可以从1,2,3,,,,n中选出三个不同的整数,可以组成三角形。
1 数学分析:
设最大边长为x的三角形与c[x]个。
y+z>x;
x-y<z<x;
枚举y的长度,就可以得到z的个数。
y==1,z无解;
y==2,z=x-1;
y==3,z=x-1 ,x-2;
......
y=x-1,z=2,3,4,,,x-1;
等差数列求和.(x-1)*(x-2)/2;
去除y==z,和重复计算的种类.
y==z有多少种呢?
y的取值从x/2+1开始到x-1为止,因为这样也能组成三角形。
c[x]=( (x-1)(x-2)/2-(x-1)/2 ) 、2;
f[x]=f[x-1]+c[x];
2 直接观察:
n为偶数时:
2 n-1 (1)
3 n-2 (2)
4 n-3
......
m m+1 (n-m-1)
m+1 m+2 (n-m-2)
.....
n-2 n-1 1
f[i]=f[i-1]+(i*i-4*i+4)/4;利用等差数列求和
n为奇数时:
2 n-1 (1)
3 n-2 (2)
4 n-3
......
m m+2 (n-m-2)
m+1 m+2 (n-m-2)
.....
n-2 n-1 1
f[i]=f[i-1]+(i-i/2-1) * (i-3) /2;
#include<stdio.h> typedef long long i64; long long f[1000000]; void solve() { f[3]=0; for(long long i=4;i<=1000000;i++) { f[i]=0; if( (i & 1)==0 ) //i为偶数 f[i]=f[i-1]+(i*i-4*i+4)/4; else f[i]=f[i-1]+(i-i/2-1) * (i-3) /2; } } int main() { solve(); int n; while(scanf("%lld",&n)!=EOF&&n>=3) { printf("%lld\n",f[n]); } return 0; }
/* 设最大边长为x的三角形有c(x)个,跟三角形的定义两边之和大于第三边有x<y+z 变形下的x-y<z<x;当y=1时无解,当y=2时只有一个解z=x-1,知道y=x-1时又x-2个解 ,所以共有(x-1)(x-2)/2个解,由于题意中不能存在y=z的解所以y=z这部分解, 当x/2+1至x-1才存在y=z的可能,共有(x-1)/2个.还过有过程中每种三角形算了两遍 所以c(x)=((x-1)(x-2)/2-(x-1)/2)/2); f(n)=c(1)+c(2)+.....+c(n); */ #include<iostream> #include<cstdio> using namespace std; __int64 f[1000010]; void Init() { __int64 i;//用int定义结果Wrong answer,不定义__int64计算过程中会溢出 f[1]=0; f[2]=0; f[3]=0; for(i=4;i<=1000000;i++) f[i]=f[i-1]+((i-1)*(i-2)/2-(i-1)/2)/2; } int main() { Init(); int n; while(cin>>n,n>=3) printf("%I64d\n",f[n]); return 0; }