任意门: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的木棒。
每组数据中,第一行是n,代表有多少个木棒,n不会超过25。接下来n行,每行4个整数x1,y1,x2,y2,代表木棒的坐标,绝对值不超过1000。
所有的木棒都是横竖摆放的,也就是说x1=x2或者y1=y2,没有长为0的木棒。
Output
对于每组测试数据,先输出一行
Case #i:
然后输出一个整数,代表有多少个长方形。
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: ", cas); 91 printf("%lld ", ans); 92 } 93 return 0; 94 }