POJ3304--Segments
2015-08-25 22:46
267 查看
题目大意:给定一些线段,问是否有直线L存在,使得所有线段到L的投影有至少一个公共点。
分析:实际上就是问,是否存在一条直线K, 和所有这些线段都相交。L是K的垂线即可。若存在一条直线与所有线段相交,该直线必定经过这些线段的某两个端点(否则可以平移或转动使之靠上端点)。枚举任意两个端点构造直线并看它是否与每条线段相交即可。
代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define eps 1e-8
struct P {
double x, y;
P() {}
P(double x, double y):x(x), y(y) {}
}p[300];
struct Seg {
P p1, p2;
}ss[110];
int n;
P operator -(P p, P q) {
return P(p.x-q.x, p.y-q.y);
}
double dist(P v1, P v2){
return sqrt((v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y));
}
double Cross(const P & v1, const P & v2) {
return v1.x * v2.y - v1.y * v2.x;
}
bool ok(P p1, P p2) {
if(dist(p1, p2) < eps) return false;
else {
for(int i = 0; i < n; i++) {
if(Cross(p2 - p1, ss[i].p1 - p1)*
Cross(p2 - p1, ss[i].p2 - p1) > eps)
return false;
}
}
return true;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%lf%lf%lf%lf", &ss[i].p1.x, &ss[i].p1.y, &ss[i].p2.x, &ss[i].p2.y);
int flag = 0;
if(n == 1) {
flag = 1;
}
else {
for(int i = 0; i < n-1 && !flag; i++)
for(int j = i+1; j < n && !flag; j++) {
if(ok(ss[i].p1, ss[j].p1) ||
ok(ss[i].p1, ss[j].p2) ||
ok(ss[i].p2, ss[j].p1) ||
ok(ss[i].p2, ss[j].p2))
flag = 1;
}
}
if(flag) printf("Yes!\n");
else printf("No!\n");
}
return 0;
}
分析:实际上就是问,是否存在一条直线K, 和所有这些线段都相交。L是K的垂线即可。若存在一条直线与所有线段相交,该直线必定经过这些线段的某两个端点(否则可以平移或转动使之靠上端点)。枚举任意两个端点构造直线并看它是否与每条线段相交即可。
代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define eps 1e-8
struct P {
double x, y;
P() {}
P(double x, double y):x(x), y(y) {}
}p[300];
struct Seg {
P p1, p2;
}ss[110];
int n;
P operator -(P p, P q) {
return P(p.x-q.x, p.y-q.y);
}
double dist(P v1, P v2){
return sqrt((v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y));
}
double Cross(const P & v1, const P & v2) {
return v1.x * v2.y - v1.y * v2.x;
}
bool ok(P p1, P p2) {
if(dist(p1, p2) < eps) return false;
else {
for(int i = 0; i < n; i++) {
if(Cross(p2 - p1, ss[i].p1 - p1)*
Cross(p2 - p1, ss[i].p2 - p1) > eps)
return false;
}
}
return true;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%lf%lf%lf%lf", &ss[i].p1.x, &ss[i].p1.y, &ss[i].p2.x, &ss[i].p2.y);
int flag = 0;
if(n == 1) {
flag = 1;
}
else {
for(int i = 0; i < n-1 && !flag; i++)
for(int j = i+1; j < n && !flag; j++) {
if(ok(ss[i].p1, ss[j].p1) ||
ok(ss[i].p1, ss[j].p2) ||
ok(ss[i].p2, ss[j].p1) ||
ok(ss[i].p2, ss[j].p2))
flag = 1;
}
}
if(flag) printf("Yes!\n");
else printf("No!\n");
}
return 0;
}
相关文章推荐
- 主机与虚拟机之间方便地共享文件----samba
- Linux下jdk1.7的安装和配置
- MyBatis传入参数与parameterType
- hdu2066 最短路 dijkstra
- 8.装饰设计模式(设计模式笔记)
- 网络爬虫:URL去重策略之布隆过滤器(BloomFilter)的使用
- 网络爬虫:URL去重策略之布隆过滤器(BloomFilter)的使用
- 笔记python函数,python学习网址
- TCP客户端和服务端的通信,通过服务端将客户端的小写字母转化成大写发送回来
- java新手笔记33 多线程、客户端、服务器
- Android第四夜
- CentOS服务进程管理
- 内存管理
- Vi使用方法总结
- gradle在android studio中应用入门
- MFC实现原理
- STL中vector的内存分配机制
- 混乱无序的整数数组如何实现左侧全是奇数右侧全是偶数(数字不要求排序)
- iptables(二)--扩展详解
- android相对布局