HDOJ(2056)&HDOJ(1086)
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)的更多相关文章
- HDOJ 2056 Rectangles
Problem Description Given two rectangles and the coordinates of two points on the diagonals of each ...
- HDOJ并查集题目 HDOJ 1213 HDOJ 1242
Problem Description Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. ...
- Kruskal HDOJ 1863 畅通工程
题目传送门 /* 此题为:HDOJ 1233 + HDOJ 1232 */ #include <cstdio> #include <algorithm> #include &l ...
- 关于KMP算法的理解
上次因为haipz组织的比赛中有道题必须用到KMP算法,因此赛后便了解了下它,在仔细拜读了孤~影神牛的文章之后有种茅塞顿开的感觉,再次ORZ. 附上链接http://www.cnblogs.com/y ...
- 【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 ...
- 【HDOJ 1086】 模板水过
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- 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 ...
- hdoj:2056
#include <iostream> #include <iomanip> #include <cstdlib> using namespace std; str ...
- 杭电hdoj题目分类
HDOJ 题目分类 //分类不是绝对的 //"*" 表示好题,需要多次回味 //"?"表示结论是正确的,但还停留在模块阶 段,需要理解,证明. //简单题看到就 ...
随机推荐
- sql server2008 检查是否需要挂起计算机重新启动。挂起重新启动会导致安装程序失败。
解决方法: 1.如果重新启动后,一样无效, 2.那么就进入注册表编辑器,通过修改注册表的方法来解决.除了删除SQL安装时遗留下的LJ文件,还必须进行以下操作: 在"开始"-&quo ...
- angularJs ng-model/ng-bind
ng-bind 与ng-model区别ng-bind是从$scope -> view的单向绑定,也就是说ng-bind是相当于{{object.xxx}},是用于展示数据的.ng-modle是$ ...
- vbs 的二个解释程序区别与切换及与BAT互调用。
WScript.exe : 窗口中运行CScript.exe :命令行中运行 用法:<CScript|WScript> scriptname.extension [option...] [ ...
- VS2010 无法计算HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0@VCTargetPath处的属性表达式
VS2010打开.csproj工程文件报错,不能加载,错误信息如下: 无法计算HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\1 ...
- Android屏幕适配全攻略 (转载)
http://blog.csdn.net/jdsjlzx/article/details/45891551 https://github.com/hongyangAndroid/AndroidAuto ...
- 使用VS2010在Coding.net上进行代码托管
网上有VS2010和Github结合使用办法,但是Github在国内使用太慢,本文使用相同的配置方法稍作改动让VS2010代码托管在coding.net平台上.由于只是稍做记录让自己不会遗忘,所以叙述 ...
- petapoco存储过程
db.ExecuteScalar<string>("exec P_GetCode @0,@1,@2,@3,@4,@5",); using (var db = new D ...
- Ejabberd外部组件开发
Ejabberd的基本介绍就不多言了,使用erlang开发的高并发高稳定性XMPP服务器,在whatsapp中得到了应用,算是erlang领域一个杀手级应用.前面的文章中我已经总结了Ejabberd插 ...
- Ubuntu12.04解决gedit中文乱码问题
Ubuntu12.04,终端中分别输入下面两条指令: gsettings set org.gnome.gedit.preferences.encodings auto-detected “['GB18 ...
- VBA_Excel_教程:单元格颜色
Sub SetCellColor() '设置单元格颜色 Sheet1.Cells(, ).Interior.ColorIndex = End Sub