csuoj 1117: 网格中的三角形

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

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)。ide

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

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

 

 

 

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",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\n", solve(B*2) - solve(A*2-1));
75     }
76     return 0;
77 }
View Code
相关文章
相关标签/搜索