【问题描述】
因为对polo忍无可忍, dzf使用圣剑在地上划出了许多纵横交错的沟壑来泄愤。这些沟壑都严格与X轴平行或垂直。 polo嘲笑了dzf无聊的行为,然后做了一件更加无聊的事。他蹲下来数这些沟壑的条数。数着数着,polo意识到一个问题,那就是因为圣剑的威力太大,划出的沟壑太多,地面就会塌陷。而如果两条水平的沟壑和两条垂直的沟壑相交组成了一个矩形,那么塌陷的危险就会进一步增加。现在polo已经数了n条沟壑,他想知道这些沟壑组成了多少个矩形。
【输入】
第一行一个数n,接下来每行4个数x1,y1,x2,y2,表示沟壑的两个端点(x1,y1),(x2,y2)
【输出】
一个数,组成的矩形个数。
【输入输出样例1】
rect.in
4
0 0 1 0
0 0 0 1
1 1 1 -1
1 1 0 1
rect.out
1
【输入输出样例2】
rect.in
8
1 0 4 0
2 1 2 0
0 0 0 3
2 2 2 3
3 3 3 -1
0 3 4 3
4 1 -1 1
3 2 -1 2
rect.out
6
【数据说明】
对于30%的数据,1<=n<=100
对于60%的数据,1<=n<=600
对于100%的数据,1<=n<=2000,坐标绝对值小于10^9,任意两条与X轴水平的沟壑之间没有交点,任意两条与X轴垂直的沟壑没有交点。
题解:
30分四重循环,60分三重循环,100分是线段树+离散化??
目前100分有些困难,线段树还好,离散化还没有学到,以后懂了再来解决吧
那么这份代码是60分做法,即枚举两条竖线(或者横线)和一条横线(或竖线)
首先把横竖线分开存,并且我们存的时候要保证x1和y1为较小的坐标,方便我们后面判断两条线段是否相交
后面三层循环枚举边,先确定两条竖线,然后再在所有横线里面找与这两条竖线都相交的有多少条
显然,从这些相交的横线中随意选择不同的两条即可组成一个矩形,那么对于这一次,
就有C(k,2)种矩形组合(k为相交条数),对于这个式子我们化简得到k*(k-1)/2,否则直接套用公式的话明显会爆掉
每一次累加答案,时间复杂度为O(n^3),可以得60分
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<climits>
#include<vector>
#include<stack>
#include<queue>
#define MAXA 200005
using namespace std;
int n,cnt_Heng,cnt_Shu,Cross;
long long Ans;
struct RX {
int x1,y1;
int x2,y2;
}Heng[MAXA],Shu[MAXA];
int main() {
// freopen("rect.in","r",stdin);
// freopen("rect.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for(int i=1;i<=n;i++) {
int t1 = 0,t2 = 0,t3 = 0,t4 = 0;
cin >> t1 >> t2 >> t3 >> t4;
if(t2 == t4) {
Heng[++cnt_Heng].x1 = min(t1,t3);
Heng[cnt_Heng].y1 = t2;
Heng[cnt_Heng].x2 = max(t1,t3);
Heng[cnt_Heng].y2 = t4;
}
if(t1 == t3) {
Shu[++cnt_Shu].x1 = t1;
Shu[cnt_Shu].y1 = min(t2,t4);
Shu[cnt_Shu].x2 = t3;
Shu[cnt_Shu].y2 = max(t2,t4);
}
}
if(n < 4) {
printf("0");
return 0;
}
for(int i=1;i<=cnt_Shu;i++)
for(int j=i+1;j<=cnt_Shu;j++) {
Cross = 0;
for(int k=1;k<=cnt_Heng;k++) {
if(Heng[k].x1 <= Shu[i].x1 && Heng[k].x1 <= Shu[j].x1 && Heng[k].x2 >= Shu[i].x1 && Heng[k].x2 >= Shu[j].x1
&& Heng[k].y1 >= Shu[i].y1 && Heng[k].y1 >= Shu[j].y1 && Heng[k].y1 <= Shu[i].y2 && Heng[k].y1 <= Shu[j].y2)
Cross++;
}
Ans += Cross * (Cross - 1) / 2;
}
cout << Ans;
}