NOJ[1313] ——Anger Begins

  • 问题描述
  • かとん--Katon
    Long long ago, when Wodex was a child, he lived happily. Unfortunately, one day, The nightmare begins...

    Some ninjas attacked his village and the village fell into a big fire.Most of villagers were died. Witnessed it, Wodex was very afraid but angry. So, Wodex wanted to revenge.To be stronger, he needed to flee out of the village first. But owing to the fire, some roads were blocked. 
    Now, there will be some roads which can be walked. Each road was straight, and the endpoint is P1 (x1, y1), P2 (x2, y2). 
    x and y is the coordinate. 

    Now he was on the road A, can he ran to road B? He can ran one road to another road if these two roads are connected. The number of road is from 1 to N. 
    It is very urgent, help him! 

  • 输入
  • Input until EOF. 
    First line is an integer N (2 <= N <= 100) means the number of roads. 
    Then N lines follow. Each line contains 4 double numbers x1, y1, x2 and y2, each number is between -1000.00 and 1000.00. 
    Next line is a integer M (1 <= M <= 200) means the number of questions. 
    Then M lines follow. Each line contains 2 integers A and B means the road A and road B.
  • 输出
  • For each question, if she can run from road A to road B, print 'YES', otherwise print 'NO'.
  • 样例输入
  • 4
    0 0 10 10
    0 10 10 0
    -1 -1 1 -1
    -2 -2 2 -2
    2
    1 2
    3 4
  • 样例输出
  • YES
    NO
  • 提示
  • 来源
  • Hungar
    给你一些线段,然后再给你一些询问,问你两条直线是否相通
那么思路就很明显了,判断线段是否有交点,以及并查集
题是水题,就看考虑的完不完全了。

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>

using namespace std;

struct node
{
double x1,x2,y1,y2;
} line[110];

int father[105];

int find(int x)
{
if(x==father[x])
return father[x];
else
father[x]=find(father[x]);
return father[x];
}

void unit(int a,int b)
{
int aa=find(a);
int bb=find(b);
if(aa!=bb)
father[aa]=bb;
}

bool judge(int a,int b)
{
double min_ay=min(line[a].y1,line[a].y2);
double max_ay=max(line[a].y1,line[a].y2);
double min_by=min(line[b].y1,line[b].y2);
double max_by=max(line[b].y1,line[b].y2);
if(line[a].x1 == line[a].x2)
{
if(line[b].x1 == line[b].x2)
{
if(line[b].x1 != line[a].x1)//平行但不重合
return false;
else
{
if(min_ay > line[b].y1 && min_ay > line[b].y2)
return false;
else if(max_ay < line[b].y1 && max_ay < line[b].y2)
return false;
else
return true;
}
}
else
{
double k2=(line[b].y1 - line[b].y2)/(line[b].x1 - line[b].x2);
double b2=line[b].y1 - k2 * line[b].x1;
double ly=k2 * line[a].x1 + b2;
if(ly>=min_ay && ly <= max_ay && ly>=min_by && ly<=max_by)
return true;
else
return false;
}
}
else
{
if(line[b].x1 == line[b].x2)
{
double k1=(line[a].y1 - line[a].y2)/(line[a].x1 - line[a].x2);
double b1=line[a].y1 - k1 * line[a].x1;
double ly=k1 * line[b].x1 + b1;
if(ly>=min_ay && ly <= max_ay && ly>=min_by && ly<=max_by)
return true;
else
return false;
}
else//两条直线都有斜率
{
double k1=(line[a].y1 - line[a].y2)/(line[a].x1 - line[a].x2);
double b1=line[a].y1 - k1 * line[a].x1;
double k2=(line[b].y1 - line[b].y2)/(line[b].x1 - line[b].x2);
double b2=line[b].y1 - k2 * line[b].x1;
if(k1 == k2)
{
if(b1 == b2)
{
if(min_ay > line[b].y1 && min_ay > line[b].y2)
return false;
else if(max_ay < line[b].y1 && max_ay < line[b].y2)
return false;
else
return true;
}
else
return false;
}
else
{
double ly=((b2-b1)/(k1-k2))*k1+b1;
if(ly>=min_ay && ly <= max_ay && ly>=min_by && ly<=max_by)
return true;
else
return false;
}
}
}
}


int main()
{
int n,m;
while(~scanf("%d",&n))
{
int a,b;
for(int i=0; i<=100; i++)
father[i]=i;
for(int i=1; i<=n; i++)
scanf("%lf%lf%lf%lf",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);
for(int i=1; i<=n; i++)
for(int j=i+1; j<=n; j++)
if(judge(i,j))
unit(i,j);
scanf("%d",&m);
for(int i=1; i<=m; i++)
{
scanf("%d%d",&a,&b);
if(find(a) == find(b))
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}


你可能感兴趣的:(NOJ[1313] ——Anger Begins)