• csuoj 1117: 网格中的三角形


    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1117

    1117: 网格中的三角形

    Time Limit: 3 Sec  Memory Limit: 64 MB
    Submit: 35  Solved: 12
    [Submit][Status][Web Board]

    Description

    有一个n行m列单位正方形组成的网格。不难发现一共有n+1条横线,m+1条竖线和它们形成的(n+1)(m+1)个交叉点。你可以选择三个不共线的交叉点,形成一个三角形。比如当n=m=1时,一共有4个交叉点,可以形成4个三角形。
    问:有多少个三角形的面积在A和B之间(包含A和B)。
     

    Input

    输入第一行为数据组数T (T<=25)。每组数据为四个整数n, m, A, B (1<=n, m<=200, 0<=A<B<=nm)。

    Output

    对于每组数据,输出面积在A和B之间的三角形个数。
     

    Sample Input

    4
    1 1 0 1
    1 2 1 2
    10 10 20 30
    12 34 56 78
    

    Sample Output

    4
    6
    27492
    1737488
    

    HINT

     

    Source

    湖南省第八届大学生计算机程序设计竞赛

    AC代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 typedef long long ll;
     7 
     8 inline ll max(ll a, ll b) {
     9     return a > b ? a : b;
    10 }
    11 
    12 inline ll min(ll a, ll b) {
    13     return a < b ? a : b;
    14 }
    15 
    16 ll N, M, A, B;
    17 
    18 ll solve (ll k) {
    19     if (k < 0)
    20         k = 0;
    21 
    22     if (N > M)
    23         swap(N, M);
    24 
    25     ll ans = 0;
    26     for (ll n = 1; n <= N; n++) {
    27         for (ll m = 1; m <= M; m++) {
    28             ll cnt = 0;
    29 
    30             if (n * m <= k)
    31                 cnt += 2 * (n + m - 2);
    32 
    33             ll l, r;
    34             for (ll x = 0; x <= n; x ++) {
    35                 r = (m * x + k) / n;
    36 
    37                 if (r > m)
    38                     r = m;
    39 
    40                 ll t = m * x - k;
    41 
    42                 if(t <= 0) 
    43                     l = 0;
    44                 else 
    45                     l = (t - 1) / n + 1;
    46 
    47                 if(l <= r) 
    48                     cnt += 2 * (r - l + 1);
    49             }
    50 
    51             for (ll x = 1; x < n; x++) {
    52                 ll tmp = n * m - x;
    53 
    54                 if (tmp <= k)
    55                     cnt += 4 * (m - 1);
    56                 else {
    57                     tmp = tmp - k;
    58                     ll u = m-1 - min(tmp / x + (tmp % x != 0), m-1);
    59                     cnt += 4 * u;
    60                 }
    61             }
    62             //printf("%lld %lld %lld
    ",n , m,  cnt);
    63             ans += cnt * (N - n + 1) * (M - m + 1);
    64         }
    65     }
    66     return ans;
    67 }
    68 
    69 int main () {
    70     int cas;
    71     scanf("%d", &cas);
    72     while (cas--) {
    73         scanf("%lld%lld%lld%lld", &N, &M, &A, &B);
    74         printf("%lld
    ", solve(B*2) - solve(A*2-1));
    75     }
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    什么是仿射变换
    转:vim比较好的学习资料
    学好C++的五十条建议
    转:美国设置地理系的大学名单
    转:windows下安装emacs
    我学习GNU/Linux: 如何上手
    Linux学习路线图 (转载)
    unix编程学习路线图(转)
    转:C++资源之不完全导引
    Why Linux Programming?
  • 原文地址:https://www.cnblogs.com/jeff-wgc/p/4478937.html
Copyright © 2020-2023  润新知