输入线段的两个短点,如果线段相交那么他们属于一个集合,查看第i条线段所在的集合有几条线段。
好久没码码了,总是各种蠢。
首先找出两条直线的方程,求解相交点的横坐标,然后看是不是在线段内部。
没有注意题目中从1开始数,我自己写的从0开始数,各种wa。
同时,又受到了杭电的输出大坑(between和fllowed两种不同!!)
#include<iostream> #include<stdio.h> using namespace std; struct po { double lx,ly,rx,ry,k,b;//线段左端点和右端点的坐标,斜率,截距 bool ok;//ok为1表示斜率存在,否则不存在 }; po me[1005]; int li[1005]; int num[1005]; void init(int a) { int i; for(i=0;i<=a;i++) { li[i]=i; num[i]=1; } } int findme(int a) { if(a!=li[a]) return li[a]=findme(li[a]); return li[a]; } int main() { int t,i,j,n,k,tmp,w,tmpk,tmpw; double tmp1,tmp2,tmp3,tmp4,tmpx; char typ; while(scanf("%d",&t)!=EOF) { getchar(); for(i=1;i<=t;i++) { scanf("%d",&n); init(n); getchar(); k=1; for(j=0;j<n;j++) { scanf("%c",&typ); if(typ==‘P‘) { scanf("%lf%lf%lf%lf",&tmp1,&tmp2,&tmp3,&tmp4); me[k].ok=1; if(tmp1<tmp3) { me[k].lx=tmp1; me[k].ly=tmp2; me[k].rx=tmp3; me[k].ry=tmp4; } else { me[k].lx=tmp3; me[k].ly=tmp4; me[k].rx=tmp1; me[k].ry=tmp2; } if(me[k].lx==me[k].rx) { me[k].ok=0; } else { me[k].k=(me[k].ly-me[k].ry)/(me[k].lx-me[k].rx); me[k].b=me[k].ly-me[k].k*me[k].lx; } for(w=k-1;w>=1;w--) { tmpk=findme(k); tmpw=findme(w); if(tmpk!=tmpw) { if(me[k].ok&&me[w].ok) { tmpx=(me[k].b-me[w].b)/(me[w].k-me[k].k); if(me[k].lx<=tmpx&&me[k].rx>=tmpx&&me[w].lx<=tmpx&&me[w].rx>=tmpx) { li[tmpk]=tmpw; num[tmpw]+=num[tmpk]; } } else if(me[k].ok) { if(me[k].lx<=me[w].lx&&me[k].rx>=me[w].rx) { li[tmpk]=tmpw; num[tmpw]+=num[tmpk]; } } else if(me[w].ok) { if(me[w].lx<=me[k].lx&&me[w].lx>=me[k].rx) { li[tmpk]=tmpw; num[tmpw]+=num[tmpk]; } } else if(me[w].lx==me[k].lx) { li[tmpk]=tmpw; num[tmpw]+=num[tmpk]; } } } k++; } else if(typ==‘Q‘) { scanf("%d",&tmp); tmp=findme(tmp); printf("%d\n",num[tmp]); } getchar(); } if(i!=t)//输出大坑 printf("\n"); } } return 0; }
时间: 2024-10-22 23:30:22