您的位置:首页 > 其它

数学推导——ACdream 1067

2017-02-16 21:25 246 查看
题目链接: http://acdream.info/problem?pid=1067

题意: 在圆上取N个点,以至将圆弧分成N等份,求任取3个点能构成多少个锐角三角形

分析: 当3个点组成锐角三角形ABC时,圆心O一定在三角形内部,∠AOB , ∠BOC, ∠COA一定小于180度(∠AOB + ∠BOC + ∠COA = 360度)

(1)当N为偶数时,用1, 2 …. k , k+1, …. , 2k来标记N个点(2K = N). 固定一个点, 如点A = 点k, 那么2k点是肯定不能选的了,因为 k, 2k组成一条直径。

所以剩下两个区间 [1, k-1], [K+1, 2k-1].如果点B, 点C同处一个区间,那么ABC一定是一个钝角三角形,所以B,C一定不可处于同一区间。

设点B = 点x, x 属于[1, k-2]; 点C=点y,y 属于[k+1, 2k-1];

在这样的情况下,y - x > k 才能使得ABC为锐角三角形 ==> (x, y)的取值有S = 0 + 1 + 2 + … + (k - 2) = (k -1) * (k -2) /2 = (N/2 - 1) * (N / 2 - 2) / 2 ;

有N个点,每个三角形被重复计算3次,所以一共有 S * N / 3种;

(2)点N为奇数时, k = N / 2. 用0, 1 … k , k + 1, 2k.

固定点A = 点0,则过点A的直径把N个点分成[1, k], [k+1, 2k]两个部分。和(1)同理,可以令 点B = 点x , x 属于[1, k], 点C = 点y, y 属于[k+1, 2k];

AC代码:

/*************************************************************************
> File Name: test.cpp
> Author: Akira
> Mail: qaq.febr2.qaq@gmail.com
************************************************************************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <queue>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <ctime>
#include <climits>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))
using namespace std;

#define MaxN 100000
#define MaxM MaxN*10
#define INF 0x3f3f3f3f
#define bug cout<<88888888<<endl;
#define MIN(x,y) (x<y?x:y)
#define MAX(x,y) (x>y?x:y)

template<typename _> inline void scan(_& t)
{
int c;
while((c = getchar()) < '0' || c > '9');
t = c - '0';
while((c = getchar()) >= '0' && c <= '9') t = t * 10 + c - '0';
}
template<typename _> inline void print(_ x)
{
int len = 0, p[20];
if(x < 0) putchar('-'), x = -x;
while(x) p[++len] = x % 10, x /= 10;
if(!len) p[++len] = 0;
while(len) putchar(p[len--] + '0');
}
/*
3 1
4 0
5 5
6 0
7 7
8 8
9 9
10
n奇数:n*(n/2)*(n/2+1)/6;
n偶数:n*(n/2-1)*(n/2-2)/6;
*/

LL N;
int main()
{
while(~scanf("%lld", &N))
{
LL ans;
if(N&1)
{
ans = N*(N/2)*(N/2+1)/6;
}
else
{
ans = N*(N/2-1)*(N/2-2)/6;
}
printf("%lld\n", ans);
}
//system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学