这个第四次练习我还真是涨姿势了。。。就这么一道叉积题,跟之前的UVA191、378看起来都要简单,可我就在怎么处理数据上卡了半天,,一直没有思路。。。总在想到底以线(两个点)为单位处理还是单个点单个点处理,,这直接导致了我不知道该如何读入这些数据,也就处理不了了。。。然后果断百度看看大牛们的经验,,有了提示,就开始写呀写。。。
一开始提交WA。。。可是样例我都对了啊,,我也注意了大佬们的提示 把二阶矩阵的叉积函数定义为long long返回型了呀。。。又找了半天。。发现了,原来是在调用叉积函数返回的时候数据发生溢出了。。。就是代码里的d1,d2,d3,d4一开始声明为int型出了问题,就这样AC。。。
一、数据处理没有经验可依据。。。
二、数据运算导致溢出。。在赋值时又可能溢出。。。
原题地址
代码贴上。
#include <iostream>
#include <cstdio>
using namespace std;
int const Maxn = (100<<1)+3;
struct point{//点结构体
int x,y;
point(int a=0,int b=0) { x=a; y=b;}//给点赋坐标值
}Point[Maxn];
int Count = 0;
int n=0,m=0;
long long det(point p1,point p2,point p3){//二维矩阵
return ( (p2.x-p1.x)*(p3.y-p1.y) - (p3.x-p1.x)*(p2.y-p1.y));//返回的是向量p1p2与p1p3叉积结果
}
bool onSegment(point p1,point p2,point p3){//利用坐标大小关系判断p3是否在线段p1p2
if( p3.x>= min(p1.x,p2.x) && p3.x<= max(p1.x,p2.x) && p3.y>=min(p1.y,p2.y) && p3.y<= max(p1.y,p2.y))
return true;
else
return false;//p1,p2,p3三点共线
}
bool checkIntersection(point p1,point p2,point p3, point p4){//线在矩形外,判断相交
long long d1,d2,d3,d4;
d1 = det(p3,p4,p1);//p3p4 and p3p1
d2 = det(p3,p4,p2);//p3p4 and p3p2
//根据叉积几何意义判断两条线段相交知:若d1与d2异号则点p1、p2分居在向量p3p4两侧,即是p1p2与p3p4相交
d3 = det(p1,p2,p3);//p1p2 and p1p3
d4 = det(p1,p2,p4);//p1p2 and p1p4
//同理,异号时p3、p4分居向量p1p2
//cout << d1 << " " << d2 <<" " << d3 << " " << d4 << endl;
if((d1*d2<0) && (d3*d4<0))
return true;//Intersecting!
else if((d1 == 0)&&( onSegment(p3,p4,p1)))//这一行代码说明p1在线段p3p4上,以下同理
return true;
else if((d2 == 0)&&( onSegment(p3,p4,p2)))
return true;
else if((d3 == 0)&&( onSegment(p1,p2,p3)))
return true;
else if((d4 == 0)&&( onSegment(p1,p2,p4)))
return true;
else
return false;
}
inline void init(){
Count = 0;
int a,b,c,d;
scanf("%d",&m);
for(int i=0; i<m; ++i){
scanf("%d%d%d%d",&a,&b,&c,&d);
Point[i<<1] = point(a,b);
Point[(i<<1)+1] = point(c,d);
}
}
inline void solve(point p[], int num){
bool flag;
for(int i=0; i<num; ++i){
flag = false;
for(int j=0; j<num; ++j){
if( j==i)
continue;
if( checkIntersection( p[i<<1],p[(i<<1)+1],p[j<<1],p[(j<<1)+1])){
flag = true;//有交点,非孤立点,排除
break;
}
}
if(!flag)//still flase
Count++;
}
}
inline void outResult(){
printf("%d\n",Count);
}
int main(){
scanf("%d",&n);
while(n--){
init();
solve( Point, m);
outResult();
}
return 0;
}
2017年03月12日 04:51:30 书
4833

被折叠的 条评论
为什么被折叠?



