HDU 5258 数长方形【离散化+暴力】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=5258

数长方形

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 303    Accepted Submission(s): 159


Problem Description
小度熊喜欢玩木棒。一天他在玩木棒的时候,发现一些木棒会形成长方形。小度熊可能是处女座吧,他只会将木棒横竖摆放,这样会形成很多长方形。现在给你一些横竖摆放的木棒,请你帮小度熊数一数形成了多少个长方形。

为了简化题目,一个木棒的端点不会在另一个木棒上,也就是说,木棒的端点不会在长方形上。
 

 

Input
第一行一个整数T,表示T组数据,不超过100组。

每组数据中,第一行是n,代表有多少个木棒,n不会超过25。接下来n行,每行4个整数 x1,y1,x2,y2,代表木棒的坐标,绝对值不超过1000。

所有的木棒都是横竖摆放的,也就是说x1=x2或者y1=y2,没有长为0的木棒。
 

 

Output
对于每组测试数据,先输出一行

Case #i:

然后输出一个整数,代表有多少个长方形。
 

 

Sample Input
2 4 3 0 3 3 4 0 4 3 2 1 5 1 2 2 5 2 4 3 0 3 3 4 0 4 3 2 1 5 1 2 2 -5 2
 

 

Sample Output
Case #1: 1 Case #2: 0
 

 

解题思路:

坐标值很大,但是木棍数很少,离散化。

暴力:

记录每一根横放的棍子有多少个相同的覆盖的点。

然后遍历枚举横放的棍子的数目,查询有多少对相同的点。也就是这些横放的棍子有多少对相同的竖放的棍子,总数 C(cnt, 2) = cnt * (cnt - 1)/ 2  就是当前枚举情况可以组成的长方形数目。

注意:

一、初始化,所有数据结构。

二、每一根棍子粗存的 x y 要按照升序的顺序。

 

AC code:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <map>
 7 #include <vector>
 8 #define INF ox3f3f3f3f
 9 #define LL long long
10 using namespace std;
11 const int MAXN = 51;
12 struct date
13 {
14     int x1, y1, x2, y2;
15 }node[MAXN<<1];
16 int mmp[MAXN][MAXN];
17 vector<int> addd[MAXN];
18 vector<int> len_X;
19 vector<int> len_Y;
20 map<int, int> HX;
21 map<int, int> HY;
22 int N;
23 
24 void init()
25 {
26     memset(node, 0, sizeof(node));
27     memset(mmp, 0, sizeof(mmp));
28     len_X.clear();
29     len_Y.clear();
30     HX.clear();
31     HY.clear();
32     for(int i = 0; i < MAXN; i++) addd[i].clear();
33 }
34 int main()
35 {
36     int T_case;
37     scanf("%d", &T_case);
38     for(int cas = 1; cas <= T_case; cas++){
39         init();
40         scanf("%d", &N);
41         for(int i = 0; i < N; i++){
42             scanf("%d%d%d%d", &node[i].x1, &node[i].y1, &node[i].x2, &node[i].y2);  ///离散化
43             if(node[i].x1 > node[i].x2) swap(node[i].x1, node[i].x2);
44             if(node[i].y1 > node[i].y2) swap(node[i].y1, node[i].y2);
45             len_X.push_back(node[i].x1), len_X.push_back(node[i].x2);
46             len_Y.push_back(node[i].y1), len_Y.push_back(node[i].y2);
47         }
48         sort(len_X.begin(), len_X.end());
49         sort(len_Y.begin(), len_Y.end());
50         len_X.erase(unique(len_X.begin(), len_X.end()), len_X.end());
51         len_Y.erase(unique(len_Y.begin(), len_Y.end()), len_Y.end());
52         for(int i = 0; i < len_X.size(); i++) HX[len_X[i]] = i;
53         for(int i = 0; i < len_Y.size(); i++) HY[len_Y[i]] = i;
54 
55         for(int i = 0; i < N; i++){
56             node[i].x1 = HX[node[i].x1], node[i].y1 = HY[node[i].y1];
57             node[i].x2 = HX[node[i].x2], node[i].y2 = HY[node[i].y2];
58         }
59 
60         for(int i = 0; i < N; i++){                                 //横放的木条
61             if(node[i].x1 == node[i].x2){
62                 for(int j = node[i].y1; j <= node[i].y2; j++)
63                     mmp[node[i].x1][j] = i+1;
64             }
65         }
66         for(int i = 0; i < N; i++){                                  //竖放的木条
67             if(node[i].y1 == node[i].y2){
68                 for(int j = node[i].x1; j <= node[i].x2; j++){
69                     if(mmp[j][node[i].y1] != 0){
70                         addd[mmp[j][node[i].y1]].push_back(i+1);
71                     }
72                 }
73             }
74         }
75         LL ans = 0;
76         for(int i = 0; i <= N; i++){
77             for(int j = i+1; j <= N; j++){
78                 int cnt = 0;
79                 for(int k = 0; k < addd[i].size(); k++){
80                     for(int m = 0; m < addd[j].size(); m++){
81                         if(addd[i][k] == addd[j][m]){
82                             cnt++;
83                             break;
84                         }
85                     }
86                 }
87                 ans+=cnt*(cnt-1)/2;
88             }
89         }
90         printf("Case #%d:\n", cas);
91         printf("%lld\n", ans);
92     }
93     return 0;
94 }
View Code

 

转载于:https://www.cnblogs.com/ymzjj/p/9637564.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值