题意:给你一些线段的起点和终点的坐标,最后问和某个线段相连的或者间接相连的线段有多少个(包括本身)?
P X1 Y1X2 Y2 起点(X1,X2)终点(X2,Y2);按照出现次数依次编号为1,2,3,4......
Q N 问和第N个线段相交或者间接相交的线段有多少个,所谓间接相交就是如果 1 和 2相交 , 2 和 3相交 那么 1 和 3 就是间接相交。。。。。
解题思路:每给出一个线段就和之前的所有线段判断是否相交,如果相交就合并,最后利用路径压缩后所有节点的父节点都是根节点的特征,找出与所问的这条线段相交的数量(包括本身)。记得最后那个换行在每个样列之间。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <algorithm>
#define EPS .1e-6
using namespace std;
const int MAXN = 1e3 + 3;
int pre[MAXN];
struct TPoint //代表一个点
{
float x,y; //横纵坐标
};
struct TLineSeg //一条线段
{
TPoint a,b; //起点和终点
};
float multiply(TPoint p1,TPoint p2,TPoint p0)
{
return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
int intersect(TLineSeg u,TLineSeg v) //判断两条是否相交
{
return( (max(u.a.x,u.b.x) >= min(v.a.x,v.b.x))&&(max(v.a.x,v.b.x) >= min(u.a.x,u.b.x))&& (max(u.a.y,u.b.y)>= min(v.a.y,v.b.y))&& (max(v.a.y,v.b.y)>= min(u.a.y,u.b.y))&& (multiply(v.a,u.b,u.a)*multiply(u.b,v.b,u.a)>=0)&&(multiply(u.a,v.b,v.a)*multiply(v.b,u.b,v.a)>=0));
}
int Find(int x)
{
int r = x;
while(pre[r] != r)
{
r = pre[r];
}
int i = x,j;
while(pre[i] != r)
{
j = i;
i = pre[i];
pre[j] = r;
}
return r;
}
void Mix(int a,int b)
{
int x = Find(a);
int y = Find(b);
if(x > y)
{
pre[x] = y;
}
if(x < y)
{
pre[y] = x;
}
}
void Mst()
{
for(int i = 1; i <= MAXN; i++)
{
pre[i] = i;
}
}
int main()
{
int T;
//freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
scanf("%d", &T);
while(T--)
{
Mst();
int N;
scanf("%d", &N);
struct TLineSeg S[MAXN];
memset(S,0,sizeof(S));
int len = 1;
while(N--)
{
char s[3] = {0};
scanf("%s",s);
if(s[0] == 'P')
{
scanf("%f%f%f%f",&S[len].a.x,&S[len].a.y,&S[len].b.x,&S[len].b.y);
if(len >= 2)
{
for(int i = 1; i <len; i++)
{
if(intersect(S[len],S[i])) //如果相交就合并
{
Mix(i,len);
}
}
}
len++;
}
if(s[0] == 'Q')
{
int num;
scanf("%d",&num);
for(int i = 1;i <= len; i++)
Find(i);
int ans = 0;
for(int i = 1; i <= len ;i++) //统计和这条线段相连的有多少个(包括本身)
if(pre[i] == pre[num])
ans++;
printf("%d\n",ans);
}
}
if(T) //记得最后有一个换行,记得最后有一个换行,记得最后有一个换行!!!!!!
cout <<endl;
}
return 0;
}