Counting Rectangles
Time Limit: 2 Seconds Memory Limit: 65536 KB
We are given a figure consisting of only horizontal and vertical line segments. Our goal is to count the number of all different rectangles formed by these segments. As an example, the number of rectangles in the Figures 1 and 2 are 5 and 0 respectively.
There are many intersection points in the figure. An intersection point is a point shared by at least two segments. The input line segments are such that each intersection point comes from the intersection of exactly one horizontal segment and one vertical segment.
Input
The first line of the file contains a single number M, which is the number of test cases in the file (1 <= M <= 10), and the rest of the file consists of the data of the test cases. Each test case begins with a line containing s (1 <= s <= 100), the number of line segments in the figure. It follows by s lines, each containing x and y coordinates of two end points of a segment respectively. The coordinates are integers in the range of 0 to 1000.
Output
The output for each test case is the number of all different rectangles in the figure described by the test case. The output for each test case must be written on a separate line.
Sample Input
2
6
0 0 0 20
0 10 25 10
20 10 20 20
0 0 10 0
10 0 10 20
0 20 20 20
3
5 0 5 20
15 5 15 25
0 10 25 10
Sample Output
5
0
The above input file contains two test cases corresponding to Figures 1 and 2 respectively.
题目大意:
就是说给你n条直线,n<=100,且这n条直线两两相互平行,都是垂直于x轴线或者垂直于y轴的。那么这n条直线中能组成的矩形有多少个?
解题思路:
直接上来就暴力吧,先开始我们只要将横着的线和竖着的线分别统计进入两个不同的类,然后从这两个类中开始依次判断。乍一看,以为是规律题,画了5组,发现,我们只要先枚举任意两条横向平行的直线,然后在寻找与这两条有交点的纵向的直线,每次增加一条竖着的直线,那么就会给tot贡献(cnt-1)*cnt/2,,多画几个就能推理出来了,然后,就这样每次两条枚举完所有的横向直线。
第一次用类写,有点手抖,但是还是1Y了。
代码:
1 # include<cstdio> 2 # include<iostream> 3 # include<fstream> 4 # include<algorithm> 5 # include<functional> 6 # include<cstring> 7 # include<string> 8 # include<cstdlib> 9 # include<iomanip> 10 # include<numeric> 11 # include<cctype> 12 # include<cmath> 13 # include<ctime> 14 # include<queue> 15 # include<stack> 16 # include<list> 17 # include<set> 18 # include<map> 19 20 using namespace std; 21 22 const double PI=4.0*atan(1.0); 23 24 typedef long long LL; 25 typedef unsigned long long ULL; 26 27 # define inf 999999999 28 # define MAX 1000+4 29 30 int num;//直线的条数 31 32 class rectangle 33 { 34 public: 35 int x1,y1,x2,y2; 36 void set ( int a,int b,int c,int d ) 37 { 38 x1 = a; 39 y1 = b; 40 x2 = c; 41 y2 = d; 42 } 43 }; 44 45 rectangle aa[MAX]; 46 rectangle bb[MAX]; 47 48 int check ( rectangle & a, rectangle & b ) 49 { 50 return b.y1<=a.y1 && a.y1<=b.y2 && a.x1<=b.x1 && b.x1<=a.x2; 51 } 52 53 int main(void) 54 { 55 int t;cin>>t; 56 while ( t-- ) 57 { 58 cin>>num; 59 int H = 0, S = 0; 60 for ( int i = 0;i < num;i++ ) 61 { 62 int x,y,x1,y1; 63 cin>>x>>y>>x1>>y1; 64 if ( x==x1 ) 65 {//竖线集 66 if ( y > y1 ) 67 { 68 aa[S++].set(x1,y1,x,y); 69 } 70 else 71 { 72 aa[S++].set(x,y,x1,y1); 73 } 74 } 75 else 76 {//横线集 77 if ( x > x1 ) 78 { 79 bb[H++].set(x1,y1,x,y); 80 } 81 else 82 { 83 bb[H++].set(x,y,x1,y1); 84 } 85 } 86 87 } 88 89 int tot = 0; 90 for ( int i = 0;i < H-1;i++ ) 91 { 92 for ( int j = i+1;j < H;j++ ) 93 { 94 int cnt = 0; 95 for ( int k = 0;k < S;k++ ) 96 { 97 if ( check( bb[i],aa[k]) && check( bb[j],aa[k]) ) 98 { 99 cnt++; 100 } 101 } 102 tot+=(cnt-1)*cnt/2; 103 } 104 } 105 106 107 cout<<tot<<endl; 108 } 109 110 111 112 113 return 0; 114 }