POJ - 3449 Geometric Shapes

题目链接

题目好理解,一张图里有多种形状的图案,分辨标有编号,问每个形状是否与其他形状相交,按字典序列出。

将题目所给的点依照形状补充完整:(根据对角关系)

正方形:已知(x0,y0),(x2,y2)

            则:x3=((x0+x2)+(y2-y0))/2;y3=((y0+y2)+(x0-x2))/2;

                   x4=((x0+x2)-(y2-y0))/2;y3=((y0+y2)-(x0-x2))/2。

矩形:已知(x0,y0),(x2,y2),(x3,y3)

          则:x4=x2+(x0-x1);y4=y2+(y0-y1)。

再逐一判断某一个形状和其他形状是否相交,根据边的交叉积运算可以得出。

注意变量书写,还有输出格式。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const double eps=1e-8;
char str[35];
int vis[35];
int cnt=0;

int sgn(double x){
	if(fabs(x)<eps)
		return 0;
	if(x<0)
		return -1;
	else return 1;
}

struct point{
	double x,y;
	point(){}
	point(double sx,double sy):x(sx),y(sy){}
	point operator -(const point &w)const{  //相减 
		return point(x-w.x,y-w.y);
	}
	double operator ^(const point &w)const{ //叉积 
		return x*w.y-y*w.x;
	}
	double operator *(const point &w)const{ //点积 
		return x*w.x+y*w.y;
	}
};

struct line{
	point st,ed;
	line(){}
	line(point sa,point sb):st(sa),ed(sb){}
}; 

bool isCross(line a,line b){  //是否相交 
	return
	max(a.st.x,a.ed.x)>=min(b.st.x,b.ed.x)&&
	max(b.st.x,b.ed.x)>=min(a.st.x,a.ed.x)&&
	max(a.st.y,a.ed.y)>=min(b.st.y,b.ed.y)&&
	max(b.st.y,b.ed.y)>=min(a.st.y,a.ed.y)&&
	sgn((b.st-a.ed)^(a.st-a.ed))*sgn((b.ed-a.ed)^(a.st-a.ed))<=0&&
	sgn((a.st-b.ed)^(b.st-b.ed))*sgn((a.ed-b.ed)^(b.st-b.ed))<=0;
}

struct shapes{
	char id;//编号
	int num; //点数
	point p[30]; //点集 
}shape[35];

bool cmp1(shapes a,shapes b){ //按编号排序 
	return a.id<b.id;
}

bool check(shapes a,shapes b){
	for(int i=0;i<a.num;i++)
		for(int j=0;j<b.num;j++)
			if(isCross(line(a.p[i],a.p[(i+1)%a.num]),line(b.p[j],b.p[(j+1)%b.num])))
				return true;  //相交
	return false; 
} 

void init(){
	scanf("%s",str);
	
	if(strcmp(str,"square")==0){ //正方形 
		shape[0].num=4;
		scanf(" (%lf,%lf)",&shape[0].p[0].x,&shape[0].p[0].y);
		scanf(" (%lf,%lf)",&shape[0].p[2].x,&shape[0].p[2].y);	
		shape[0].p[1].x=((shape[0].p[0].x+shape[0].p[2].x)+(shape[0].p[2].y-shape[0].p[0].y))/2;
		shape[0].p[1].y=((shape[0].p[0].y+shape[0].p[2].y)+(shape[0].p[0].x-shape[0].p[2].x))/2;
		shape[0].p[3].x=((shape[0].p[0].x+shape[0].p[2].x)-(shape[0].p[2].y-shape[0].p[0].y))/2;
		shape[0].p[3].y=((shape[0].p[0].y+shape[0].p[2].y)-(shape[0].p[0].x-shape[0].p[2].x))/2;
	}
	else if(strcmp(str,"line")==0){  //线段
		shape[0].num=2;
		for(int i=0;i<2;i++)
			scanf(" (%lf,%lf)",&shape[0].p[i].x,&shape[0].p[i].y);	
	}
	else if(strcmp(str,"triangle")==0){ //三角形
		shape[0].num=3;
		for(int i=0;i<3;i++)
			scanf(" (%lf,%lf)",&shape[0].p[i].x,&shape[0].p[i].y);	
	}
	else if(strcmp(str,"rectangle")==0){ //矩形
		shape[0].num=4;
		for(int i=0;i<3;i++)
			scanf(" (%lf,%lf)",&shape[0].p[i].x,&shape[0].p[i].y);
		shape[0].p[3].x=shape[0].p[2].x+(shape[0].p[0].x-shape[0].p[1].x);
		shape[0].p[3].y=shape[0].p[2].y+(shape[0].p[0].y-shape[0].p[1].y);
	}
	else if(strcmp(str,"polygon")==0){ //多边形
		scanf("%d",&shape[0].num);
		for(int i=0;i<shape[0].num;i++)
			scanf(" (%lf,%lf)",&shape[0].p[i].x,&shape[0].p[i].y);
	}
	
	cnt=1;
	while(~scanf("%s",str)){
		if(str[0]=='-') break;
		shape[cnt].id=str[0];
		scanf("%s",str);
		
		if(strcmp(str,"square")==0){ //正方形 
			shape[cnt].num=4;
			scanf(" (%lf,%lf)",&shape[cnt].p[0].x,&shape[cnt].p[0].y);
			scanf(" (%lf,%lf)",&shape[cnt].p[2].x,&shape[cnt].p[2].y);	
			shape[cnt].p[1].x=((shape[cnt].p[0].x+shape[cnt].p[2].x)+(shape[cnt].p[2].y-shape[cnt].p[0].y))/2;
			shape[cnt].p[1].y=((shape[cnt].p[0].y+shape[cnt].p[2].y)+(shape[cnt].p[0].x-shape[cnt].p[2].x))/2;
			shape[cnt].p[3].x=((shape[cnt].p[0].x+shape[cnt].p[2].x)-(shape[cnt].p[2].y-shape[cnt].p[0].y))/2;
			shape[cnt].p[3].y=((shape[cnt].p[0].y+shape[cnt].p[2].y)-(shape[cnt].p[0].x-shape[cnt].p[2].x))/2;
		}
		else if(strcmp(str,"line")==0){  //线段
			shape[cnt].num=2;
			for(int i=0;i<2;i++)
				scanf(" (%lf,%lf)",&shape[cnt].p[i].x,&shape[cnt].p[i].y);	
		}
		else if(strcmp(str,"triangle")==0){ //三角形
			shape[cnt].num=3;
			for(int i=0;i<3;i++)
				scanf(" (%lf,%lf)",&shape[cnt].p[i].x,&shape[cnt].p[i].y);	
		}
		else if(strcmp(str,"rectangle")==0){ //矩形
			shape[cnt].num=4;
			for(int i=0;i<3;i++)
				scanf(" (%lf,%lf)",&shape[cnt].p[i].x,&shape[cnt].p[i].y);
			shape[cnt].p[3].x=shape[cnt].p[2].x+(shape[cnt].p[0].x-shape[cnt].p[1].x);
			shape[cnt].p[3].y=shape[cnt].p[2].y+(shape[cnt].p[0].y-shape[cnt].p[1].y);
		}
		else if(strcmp(str,"polygon")==0){ //多边形
			scanf("%d",&shape[cnt].num);
			for(int i=0;i<shape[cnt].num;i++)
				scanf(" (%lf,%lf)",&shape[cnt].p[i].x,&shape[cnt].p[i].y);
		}
		
		cnt++;	
	}
	sort(shape,shape+cnt,cmp1);
}

void work(){
	int n=cnt;
	for(int i=0;i<n;i++){
		printf("%c ",shape[i].id);
		memset(vis,0,sizeof(vis));
		int t=0;
		for(int j=0;j<n;j++)
			if(i!=j)
				if(check(shape[i],shape[j])){ //相交 
					t++;
					vis[j]=1;
				}
		
		if(t==0) //没有和其他的相交
			printf("has no intersections\n");
		else if(t==1){
			printf("intersects with ");
			for(int j=0;j<n;j++)
				if(vis[j]){
					printf("%c\n",shape[j].id);break;
				}
		} 
		else if(t==2){
			printf("intersects with ");
			for(int j=0;j<n;j++)
				if(vis[j]){
					if(t==2)
						printf("%c ",shape[j].id);
					if(t==1)
						printf("and %c\n",shape[j].id);
					t--;
				}
		}
		else{
			printf("intersects with ");
			for(int j=0;j<n;j++)
				if(vis[j]){
					if(t>=2)
						printf("%c, ",shape[j].id);
					if(t==1)
						printf("and %c\n",shape[j].id);
					t--;
				}
		}
	}
	printf("\n");
}

int main(){
	while(~scanf("%s",str)){
		if(str[0]=='.') break;
		shape[0].id=str[0];
		init();
		work();
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值