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",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

 

你可能感兴趣的:(OJ)