LOJ 1307 Counting Triangles

来源:互联网 发布:网络配音兼职 编辑:程序博客网 时间:2024/05/22 02:26

题目大意:

        现有N根长度各异的木棍(3 ≤ N ≤ 2000),问共可以组成多少个不同的三角形。

        现有多个测例(测例数会告诉你),每个测例中给定N以及N根木棍的长度(每根木棍长度范围为[1, 10^9]),对于每个测例都打印出可以组成的三角形的总数量。

题目链接

注释代码:

/*                                        * Problem ID : LOJ 1307 Counting Triangles  * Author     : Lirx.t.Una                                        * Language   : C++                       * CPU        : 1.384                                        * Memory     : 1696                                       */#include <algorithm>#include <iostream>#include <cstdio>//maximum number of sticks//木棍的最大数量#define MAXSTICKN       2001using namespace std;int     a[MAXSTICKN];//存储每根木棍的数量intmain() {    int     nscn, iscn;    int     n;//木棍数量    int     i, j;//计数变量    int     lft, rht;//临时区间界限    int     ans;    scanf("%d", &nscn);    iscn = 0;    while ( nscn-- ) {        scanf("%d", &n);        for ( i = 0; i < n; i++ )            scanf("%d", a + i);        sort(a, a + n);//排序后以便二分查找//从左往右扫描,先确定两根木棍i、j//再根据三角形规则确定后面的第三根        for ( ans = 0, i = 0; i < n - 2; i++ )            for ( j = i + 1; j < n - 1; j++ ) {                lft = a[j] - a[i] + 1;//第三边一定大于前两遍之差(+1表示大于)                rht = a[i] + a[j] - 1;//第三遍一定小于前两遍之和(-1表示小于)                lft = lower_bound(a, a + n, lft) - a;//二分找出大于等于lft的第一个元素在数组中的位置                rht = upper_bound(a + lft, a + n, rht) - a - 1;//二分找出大于rht的第一个元素在数组中的位置//两个重要的剪枝,如果lft和rht都在j前面表示之前已经计算过了,可不用重复计算                if ( lft <= j )                    lft = j + 1;                if ( rht <= j )//rht小于等于j就表示无第三根可以组成三角形的木棍了,因为可行区间在[lft, rht]上                    continue;                if ( lft <= rht )//如果lft大于rht也表示这样的三角形不存在了                    ans += rht - lft + 1;            }printf("Case %d: %d\n", ++iscn, ans);    }    return 0;}

无注释代码:

#include <algorithm>#include <iostream>#include <cstdio>#define MAXSTICKN       2001using namespace std;int     a[MAXSTICKN];intmain() {    int     nscn, iscn;    int     n;    int     i, j;    int     lft, rht;    int     ans;    scanf("%d", &nscn);    iscn = 0;    while ( nscn-- ) {        scanf("%d", &n);        for ( i = 0; i < n; i++ )            scanf("%d", a + i);        sort(a, a + n);        for ( ans = 0, i = 0; i < n - 2; i++ )            for ( j = i + 1; j < n - 1; j++ ) {                lft = a[j] - a[i] + 1;                rht = a[i] + a[j] - 1;                lft = lower_bound(a, a + n, lft) - a;                rht = upper_bound(a + lft, a + n, rht) - a - 1;                if ( lft <= j )                    lft = j + 1;                if ( rht <= j )                    continue;                if ( lft <= rht )                    ans += rht - lft + 1;            }printf("Case %d: %d\n", ++iscn, ans);    }    return 0;}

单词解释:

triangle:n, 三角,三角形

stick:n, 木棍

valid:adj, 有效的,合法的,正当的

0 0
原创粉丝点击