Rectangles    HDOJ(2056)

http://acm.hdu.edu.cn/showproblem.php?pid=2056

题目描述:给2条线段,分别构成2个矩形,求2个矩形相交面积。

算法:先用快速排斥判断2个矩形是否相交。若不相交,面积为0。若相交,将x坐标排序去中间2个值之差,y坐标也一样。最后将2个差相乘得到最后结果。

这题是我大一的时候做过的,当时一看觉得很水,写起来发现其实没我想的那么水。分了好几类情况没做出来。今天看了点关于判断线段相交的知识,想起了这题便拿来练手。快速排斥之后又准备分类讨论,越想分类情况越多。后来意外想到了取各自坐标方向的2个中值之差(如x1,x2,x3,x4,是按从小到大排列的,取x3-x2,同理y3-y2)。最后2个差相乘就是相交面积。泪牛满面!

#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
int cmp(const void *a,const void *b)
{
return *(double*)a-*(double*)b;
}
double min(double a,double b)
{
return a<b?a:b;
}
double max(double a,double b)
{
return a>b?a:b;
}
bool intersected(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
{
if(min(x1,x2)<max(x3,x4)&&
min(x3,x4)<max(x1,x2)&&
min(y1,y2)<max(y3,y4)&&
min(y3,y4)<max(y1,y2)) //快速排斥判断2矩形是否相交
return true;
else
return false;
}
double getmiddiff(double a[]) //取次小和次大的2个数之差,没想到好的办法,于是用了快排
{
qsort(a,,sizeof(double),cmp);
return a[]-a[];
}
int main()
{
double x1,y1,x2,y2,x3,y3,x4,y4;
double temp[];
while(cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4)
{
if(intersected(x1,y1,x2,y2,x3,y3,x4,y4))
{
temp[]=x1;
temp[]=x2;
temp[]=x3;
temp[]=x4;
double xdiff=getmiddiff(temp);
temp[]=y1;
temp[]=y2;
temp[]=y3;
temp[]=y4;
double ydiff=getmiddiff(temp);
cout<<fixed<<setprecision()<<xdiff*ydiff<<endl; //需要<iomanip>
}
else
cout<<"0.00"<<endl; //一开始是cout<<"0"<<endl;WA了一次,SB
}
return ;
}

You can Solve a Geometry Problem too     HDOJ(1086)

http://acm.hdu.edu.cn/showproblem.php?pid=1086

题目描述:给n条线段,求相交点的个数。

算法:老套路,遍历任意两条线段,用快速排斥判断2个矩形是否相交。这题用跨立实验,即以其中一条线段为直线,判断另一线段的两端点是否在它两边。使用2次跨立实验。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct line
{
double x1,y1;
double x2,y2;
};
bool Exclude(line l1,line l2) //快速排斥
{
if(min(l1.x1,l1.x2)<=max(l2.x1,l2.x2)
&&min(l2.x1,l2.x2)<=max(l1.x1,l1.x2)
&&min(l1.y1,l1.y2)<=max(l2.y1,l2.y2)
&&min(l2.y1,l2.y2)<=max(l1.y1,l1.y2)) //相等的时候说明2个矩形有公共点
return true;
else
return false;
}
bool Straddle(line l1,line l2) //跨立实验
{
//3个向量
double t1=l1.x1-l1.x2;
double w1=l1.y1-l1.y2; double t2=l1.x1-l2.x1;
double w2=l1.y1-l2.y1; double t3=l1.x1-l2.x2;
double w3=l1.y1-l2.y2;
//求叉积
double cross1_2=(t1*w2-t2*w1);
double cross1_3=(t1*w3-t3*w1);
if(cross1_2*cross1_3<=)
return true;
else
return false;
}
bool isIntersect(line l1,line l2)
{
if(Exclude(l1,l2)&&Straddle(l1,l2)&&Straddle(l2,l1))
return true;
else
return false;
}
int main()
{
int n,res;
vector<line> v;
while(cin>>n&&n)
{
v.clear();
line temp;
res=;
for(int i=;i<n;i++)
{
cin>>temp.x1>>temp.y1>>temp.x2>>temp.y2;
v.push_back(temp);
}
int len=v.size();
for(int i=;i<len-;i++)
{
for(int j=i+;j<len;j++)
{
if(isIntersect(v[i],v[j]))
res++;
}
}
cout<<res<<endl;
}
return ;
}

跨立实验可用叉积来解决:设这四个点为x1,y1,x2,y2,x3,y3,x4,y4L1的坐标为t1=x1-x2,w1=y1-y2,1端点到3,4的线段向量分别为t2=x1-x3,w2=y1-y3,t3=x1-x4,w3=y1-y4;则3,4在L1两端即为(t1*w2-t2*w1)*(t1*w3-t3*w1)<=0 ,如果等于0则有一点在直线L1上,属于非规范相交判断L1的两点在L2两侧同理。

HDOJ(2056)&HDOJ(1086)的更多相关文章

  1. HDOJ 2056 Rectangles

    Problem Description Given two rectangles and the coordinates of two points on the diagonals of each ...

  2. HDOJ并查集题目 HDOJ 1213 HDOJ 1242

    Problem Description Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. ...

  3. Kruskal HDOJ 1863 畅通工程

    题目传送门 /* 此题为:HDOJ 1233 + HDOJ 1232 */ #include <cstdio> #include <algorithm> #include &l ...

  4. 关于KMP算法的理解

    上次因为haipz组织的比赛中有道题必须用到KMP算法,因此赛后便了解了下它,在仔细拜读了孤~影神牛的文章之后有种茅塞顿开的感觉,再次ORZ. 附上链接http://www.cnblogs.com/y ...

  5. 【HDOJ】1086 You can Solve a Geometry Problem too

    数学题,证明AB和CD.只需证明C.D在AB直线两侧,并且A.B在CD直线两侧.公式为:(ABxAC)*(ABxAD)<= 0 and(CDxCA)*(CDxCB)<= 0 #includ ...

  6. 【HDOJ 1086】 模板水过

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3 ...

  7. Hdoj 1086.You can Solve a Geometry Problem too 题解

    Problem Description Many geometry(几何)problems were designed in the ACM/ICPC. And now, I also prepare ...

  8. hdoj:2056

    #include <iostream> #include <iomanip> #include <cstdlib> using namespace std; str ...

  9. 杭电hdoj题目分类

    HDOJ 题目分类 //分类不是绝对的 //"*" 表示好题,需要多次回味 //"?"表示结论是正确的,但还停留在模块阶 段,需要理解,证明. //简单题看到就 ...

随机推荐

  1. sql server2008 检查是否需要挂起计算机重新启动。挂起重新启动会导致安装程序失败。

    解决方法: 1.如果重新启动后,一样无效, 2.那么就进入注册表编辑器,通过修改注册表的方法来解决.除了删除SQL安装时遗留下的LJ文件,还必须进行以下操作: 在"开始"-&quo ...

  2. angularJs ng-model/ng-bind

    ng-bind 与ng-model区别ng-bind是从$scope -> view的单向绑定,也就是说ng-bind是相当于{{object.xxx}},是用于展示数据的.ng-modle是$ ...

  3. vbs 的二个解释程序区别与切换及与BAT互调用。

    WScript.exe : 窗口中运行CScript.exe :命令行中运行 用法:<CScript|WScript> scriptname.extension [option...] [ ...

  4. VS2010 无法计算HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0@VCTargetPath处的属性表达式

    VS2010打开.csproj工程文件报错,不能加载,错误信息如下: 无法计算HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\1 ...

  5. Android屏幕适配全攻略 (转载)

    http://blog.csdn.net/jdsjlzx/article/details/45891551 https://github.com/hongyangAndroid/AndroidAuto ...

  6. 使用VS2010在Coding.net上进行代码托管

    网上有VS2010和Github结合使用办法,但是Github在国内使用太慢,本文使用相同的配置方法稍作改动让VS2010代码托管在coding.net平台上.由于只是稍做记录让自己不会遗忘,所以叙述 ...

  7. petapoco存储过程

    db.ExecuteScalar<string>("exec P_GetCode @0,@1,@2,@3,@4,@5",); using (var db = new D ...

  8. Ejabberd外部组件开发

    Ejabberd的基本介绍就不多言了,使用erlang开发的高并发高稳定性XMPP服务器,在whatsapp中得到了应用,算是erlang领域一个杀手级应用.前面的文章中我已经总结了Ejabberd插 ...

  9. Ubuntu12.04解决gedit中文乱码问题

    Ubuntu12.04,终端中分别输入下面两条指令: gsettings set org.gnome.gedit.preferences.encodings auto-detected “['GB18 ...

  10. VBA_Excel_教程:单元格颜色

    Sub SetCellColor() '设置单元格颜色 Sheet1.Cells(, ).Interior.ColorIndex = End Sub