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 题目分类 //分类不是绝对的 //"*" 表示好题,需要多次回味 //"?"表示结论是正确的,但还停留在模块阶 段,需要理解,证明. //简单题看到就 ...
随机推荐
- 工程中建立多个src目录
android 工程下可以有多个源代码的目录,不一定都要放到src下面.可以在 .classpath 文件中添加. 默认是这样的: <classpath> <classpathent ...
- OAF_开发系列13_实现OAF通过Vector动态查询设置(案例)
20150715 Created By BaoXinjian
- Cassandra 介绍
cassandra是一种NoSQL数据库,No是指No Relational.cassandra的数据模型结合了Dynamo的key/value和BigTable 的面向列的特点,主要被设计为存储大 ...
- PLSQL Developer图形化窗口创建数据库全过程
1.用系统管理员登陆,我这里用户名是system,密码是manager2.首先建立表空间(tablespaces),点击file->new->sql window create tab ...
- iOS 跳转至AppStore评分页面
iOS7之前: [[UIApplication sharedApplication]openURL:[NSURL URLWithString:@"itms-apps://ax.itunes. ...
- js正则表达式学习
//几种字符串操作:var str = 'abcdef'; alert(str.search('b')); //弹出1:返回的是b在str中的位置:如果找不到返回-1: alert(str.subst ...
- Jsp与servlet本质上的区别
1.jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)2.jsp更擅长 ...
- mvc通过controller创建交互接口
public JsonResult Home(string userName, string password, string type) { List<person> list = ne ...
- mac 10.9 安装 gevent
安装步骤: Gevent依赖libevent和greenlet,需要分别安装. 1,安装 macport (如已安装,可以跳过) 2,通过终端 键入: sudo port install libeve ...
- .gitignore 使用中注意的问题
在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改 .gitignore 文件的方法.这个文件每一行保存了一个匹配的规则例如: # 此为注释 – 将被 Git 忽略 *.a ...