| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
关于题意和算法上面的一些注意点+代码1. 所谓相交,不包括一个图形在另一个里面的情况,即仅只有线段相交才算
2. 对于任意两个线段,在本题中,只要是有任意公共点即当作相交
3. 代码比较长,注意细节
4. 对于点对的读入,可以用下面的方法来快速读入:
scanf(" (%lf,%lf)",&x,&y);
注意: ↑这里有一个空格!!
5. 处理和输出前,图形要按照编号排序
6. 编号只有单个大写字母
7. 这里正方形可以采用计算中点+(初中数学基本模型)一线三等角来计算,
具体公式见代码
8. 长方形的三个点是连续的3个点(一开始我还以为是任意的,还写了根据最
长边swap的代码(可惜写错了,导致了一次wa),其实不用),计算第四个
点就可以采用对应点平移的方法,具体公式见代码
代码:
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define sqr(a) ((a)*(a))
using namespace std;
const double Eps=1e-8;
struct Point{
double x,y;
void read(){
scanf(" (%lf,%lf)",&x,&y);
}
};
struct Line{
Point a,b;
void build(Point a_,Point b_){
a=a_,b=b_;
}
};
struct Polygon{
char bh;//编号
int n,e;//n为点数,e为边数
Point P[20+5];//存点
Line L[20+5];//存边
void buildL(){//根据点的信息建立相应的边(线段)
if (n==2){
e=1;
L[1].build(P[1],P[2]);
return;
}
e=n;
for (int i=1;i<n;i++)
L[i].build(P[i],P[i+1]);
L[n].build(P[n],P[1]);
}
}p[26+5];
double Cross(Point a,Point b,Point c){
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
bool FCross(Point a,Point b,Point c){
return Cross(a,b,c)<0;
}
bool BeInTwoSide(Line a,Line b){
if (fabs(Cross(a.a,a.b,b.a))<Eps||fabs(Cross(a.a,a.b,b.b))<Eps)
return 1;
return FCross(a.a,a.b,b.a)^FCross(a.a,a.b,b.b);
}
bool LCrossEachOther(Line a,Line b){//判断两个线段是否相交
if (fabs(Cross(a.a,b.a,a.b))<Eps&&fabs(Cross(a.a,b.b,a.b))<Eps&&
fabs(Cross(b.a,a.a,b.b))<Eps&&fabs(Cross(b.a,a.b,b.b))<Eps)
{
if (fabs(a.a.x-a.b.x)<Eps){
return (min(a.a.y,a.b.y)<=b.a.y&&b.a.y<=max(a.a.y,a.b.y))||
(min(a.a.y,a.b.y)<=b.b.y&&b.b.y<=max(a.a.y,a.b.y));
}
else {
return (min(a.a.x,a.b.x)<=b.a.x&&b.a.x<=max(a.a.x,a.b.x))||
(min(a.a.x,a.b.x)<=b.b.x&&b.b.x<=max(a.a.x,a.b.x));
}
}
return BeInTwoSide(a,b)&&BeInTwoSide(b,a);
}
bool PCrossEachOther(Polygon a,Polygon b){//判断两个图形是否相交
for (int i=1;i<=a.e;i++)
for (int j=1;j<=b.e;j++)
if (LCrossEachOther(a.L[i],b.L[j]))
return 1;
return 0;
}
bool PolygonBhCmp(Polygon a,Polygon b){//用于图形标号排序
return a.bh<b.bh;
}
int n;
char str[15];
int main(){
while (1){
n=0;
while (1){
n++;
scanf("%s",str);
if (n==1&&str[0]=='.')
return 0;
if (str[0]=='-'){
n--;
break;
}
p[n].bh=str[0];
scanf("%s",str);
if (str[0]=='s'){//正方形
Point a,b,c,d,mid;
a.read(),c.read();
mid.x=(a.x+c.x)/2;
mid.y=(a.y+c.y)/2;
b.x=mid.x+a.y-mid.y;
b.y=mid.y-a.x+mid.x;
d.x=mid.x*2-b.x;
d.y=mid.y*2-b.y;
p[n].n=4;
p[n].P[1]=a,p[n].P[2]=b,p[n].P[3]=c,p[n].P[4]=d;
}
if (str[0]=='r'){//矩形
Point a,b,c,d;
a.read(),b.read(),c.read();
d.x=c.x+a.x-b.x;
d.y=c.y+a.y-b.y;
p[n].n=4;
p[n].P[1]=a,p[n].P[2]=b,p[n].P[3]=c,p[n].P[4]=d;
}
if (str[0]=='l'){//线段
p[n].n=2;
p[n].P[1].read(),p[n].P[2].read();
}
if (str[0]=='t'){//三角形
p[n].n=3;
p[n].P[1].read(),p[n].P[2].read(),p[n].P[3].read();
}
if (str[0]=='p'){//多边形
scanf("%d",&p[n].n);
for (int i=1;i<=p[n].n;i++)
p[n].P[i].read();
}
p[n].buildL();
}
sort(p+1,p+n+1,PolygonBhCmp);
for (int i=1;i<=n;i++){
int cnt=0;
char ans[26+5];
for (int j=1;j<=n;j++){
if (j==i)
continue;
if (PCrossEachOther(p[i],p[j]))
ans[++cnt]=p[j].bh;
}
printf("%c ",p[i].bh);
if (cnt==0)
puts("has no intersections");
else {
printf("intersects with ");
if (cnt==1)
printf("%c\n",ans[1]);
else if (cnt==2)
printf("%c and %c\n",ans[1],ans[2]);
else {
for (int k=1;k<cnt;k++)
printf("%c, ",ans[k]);
printf("and %c\n",ans[cnt]);
}
}
}
puts("");
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator