POJ - 1127 Jack Straws(几何)
题意:桌子上放着n根木棍,已知木棍两端的坐标。给定几对木棍,判断每对木棍是否相连。当两根木棍之间有公共点或可以通过相连的木棍间接的连在一起,则认为是相连的。
分析:
1、若线段i与j平行,且有部分重合,则相连。否则,求直线i与直线j交点,再判断该交点是否在两线段上,以确定是否相连。
2、flod整理一下所有的关系。
3、判断点是否在线段上:(线段i,点t)
(1)外积(l[i] - t) × (r[i] - t) = 0, 可判断点x是否在直线i上(两向量叉乘为0,两向量平行)
(2)内积(l[i] - x) · (r[i] - x) <= 0, 可判断点x是否落在l[i]与r[i]之间。(以x为顶点,l[i] - x和r[i] - x为边的角a,当内积<0----a = 180°,当内积=0,x与l[i]重合或x与r[i]重合)。
4、求两直线交点:(直线i,直线j)
(1)直线i上的某点t可表示为l[i] + w(r[i] - l[i]),w为系数
(2)点t在直线j上可表示为(l[j] - t) × (r[j] - t) = 0,由此可算出系数w,但由于t的表达式过于复杂,所以改用(r[j] - l[j]) × (t - l[j]) = 0来判断点t是否在直线j上
解得,w = ((r[j] - l[j]) × (l[j] - l[i])) / ((r[j] - l[j]) × (r[i] - l[i]))。
(3)将求出的w代入t,此时t为直线i与j的交点,但该交点不一定在线段i与j上,所以要判断后才可确定线段i与j是否相连。
#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
const double eps = 1e-10;
inline int dcmp(double a, double b){
if(fabs(a - b) < eps) return 0;
return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN = 13 + 10;
const int MAXT = 10000 + 10;
using namespace std;
int vis[MAXN][MAXN];
int N;
double add(double a, double b){//考虑误差的加法运算
if(abs(a + b) < eps * (abs(a) + abs(b))) return 0;
return a + b;
}
struct Point{
double x, y;
void read(){
scanf("%lf%lf", &x, &y);
}
Point(){}
Point(double xx, double yy):x(xx), y(yy){}
Point operator + (Point p){
return Point(add(x, p.x), add(y, p.y));
}
Point operator - (Point p){
return Point(add(x, -p.x), add(y, -p.y));
}
Point operator * (double t){
return Point(x * t, y * t);
}
double dot(Point p){//内积
return add(x * p.x, y * p.y);
}
double det(Point p){//外积
return add(x * p.y, -y * p.x);
}
}l[MAXN], r[MAXN];//线段的左右端点
bool onsegment(Point A, Point B, Point x){//判断点x是否在以A,B为端点的线段上
return (A - x).det(B - x) == 0 && (A - x).dot(B - x) <= 0;
}
Point intersection(Point l1, Point r1, Point l2, Point r2){//计算直线1与直线2的交点(l1--直线1的左端点,r1--直线1的右端点)
return l1 + (r1 - l1) * ((r2 - l2).det(l2 - l1) / (r2 - l2).det(r1 - l1));
}
bool judge(Point l1, Point r1, Point l2, Point r2){
if(onsegment(l1, r1, l2)) return true;
if(onsegment(l1, r1, r2)) return true;
if(onsegment(l2, r2, l1)) return true;
if(onsegment(l2, r2, r1)) return true;
return false;
}
void solve(){
for(int i = 0; i < N; ++i){
vis[i][i] = 1;
for(int j = 0; j < i; ++j){
if((l[i] - r[i]).det(l[j] - r[j]) == 0){//线段i与线段j平行
if(judge(l[i], r[i], l[j], r[j])){
vis[i][j] = vis[j][i] = 1;//两线段有部分重合,相连
}
}
else{
Point x = intersection(l[i], r[i], l[j], r[j]);//x为直线i与直线j的交点
vis[i][j] = vis[j][i] = onsegment(l[i], r[i], x) && onsegment(l[j], r[j], x);//需要判断该交点是否在两个线段上
}
}
}
for(int k = 0; k < N; ++k){
for(int i = 0; i < N; ++i){
for(int j = 0; j < N; ++j){
vis[i][j] |= vis[i][k] && vis[k][j];
}
}
}
}
int main(){
while(scanf("%d", &N) == 1){
if(!N) return 0;
memset(vis, 0, sizeof vis);
for(int i = 0; i < N; ++i){
l[i].read();
r[i].read();
}
solve();
int a, b;
while(scanf("%d%d", &a, &b) == 2){
if(!a && !b) break;
if(vis[a - 1][b - 1]){
printf("CONNECTED\n");
}
else{
printf("NOT CONNECTED\n");
}
}
}
return 0;
}
POJ - 1127 Jack Straws(几何)的更多相关文章
- poj 1127:Jack Straws(判断两线段相交 + 并查集)
Jack Straws Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2911 Accepted: 1322 Descr ...
- poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)
Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped ...
- POJ 1127 Jack Straws (计算几何)
[题目链接] http://poj.org/problem?id=1127 [题目大意] 在二维平面中,给出一些木棍的左右端点,当木棍相交或者间接相交时 我们判断其连通,给出一些询问,问某两个木棍是否 ...
- POJ 1127 Jack Straws(计算几何)
题目链接 抄的模版,居然1Y了.就是简单的线段相交+并查集. #include <iostream> #include <cstring> #include <cstdi ...
- [poj 1127]Jack Straws[线段相交][并查集]
题意: 给出一系列线段,判断某两个线段是否连通. 思路: 根据线段相交情况建立并查集, 在同一并查集中则连通. (第一反应是强连通分量...实际上只要判断共存即可, 具体的方向啊是没有关系的..) 并 ...
- POJ 1127 Jack Straws (线段相交)
题意:给定一堆线段,然后有询问,问这两个线段是不是相交,并且如果间接相交也可以. 析:可以用并查集和线段相交来做,也可以用Floyd来做,相交就是一个模板题. 代码如下: #pragma commen ...
- TTTTTTTTTTTTTT poj 1127 Jack Straws 线段相交+并查集
题意: 有n个木棍,给出木棍的两个端点的x,y坐标,判断其中某两个线段是否连通(可通过其他线段连通) #include <iostream> #include <cstdio> ...
- Jack Straws POJ - 1127 (几何计算)
Jack Straws Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5428 Accepted: 2461 Descr ...
- Jack Straws POJ - 1127 (简单几何计算 + 并查集)
In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table ...
随机推荐
- SQLSERVER|CDC 日志变更捕获机制
先说一下什么是cdc ,cdc 变更数据捕获(Change Data Capture ,简称 CDC)记录 SQL Server 表的插入.更新和删除活动.SQLServer的操作会写日志,这也是CD ...
- Program-Language
1. 主流编程语言 2. 编程语言分类 2.1 编译or解释 2.2 按照客观系统的描述可分为两类 2.3 按照编程范型可分为 3. 语言范式 Paradigm 4. 计算机语 ...
- R 《回归分析与线性统计模型》page93.6
rm(list = ls()) #数据处理 library(openxlsx) library(car) library(lmtest) data = read.xlsx("xiti4.xl ...
- css的手机适配
在html篇里提到设置视口宽度和设备宽度,固定的meta配置就是写死的,==死记硬背== 应该清楚的是手机端的适配应该克服的难题就是宽度根据手机屏幕的大小变化,而高度却没有办法跟随比例变化,也就是宽高 ...
- 7.11 如何应用Varnish
动态数据缓存 Step 1 修改devault.vcl文件 # This ) # man page for details on VCL syntax and semantics. # # Defau ...
- DOM基础1
Document Object Model 文档对象模型 1.改内容: innerHTML 例:div1.innerHTML = "我能干<br />什么"; ...
- Python中基于Unpacking与Packing进行分割,组合操作的嵌套元组数据结构的应用
对于二叉树,图等,Python可采用基于Packing与Unpacking形成的嵌套元组数据结构来模拟,这里Packing指,比如a=b,c则,a就成了一个包含b,c的元组,Unpacking是指,比 ...
- LeetCode1005 K次取反后最大化的数组和(贪心+Java简单排序)
题目: 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次.(我们可以多次选择同一个索引 i.) 以这种方式修 ...
- vuejs+thinkphp5+phpsocketIO+timer数据及时更新
1.安装thinkphp5.0以上版本包含workerman框架2.composer安装composer require workerman/phpsocket.io3.vue中调用需要加载weapp ...
- Spring 实战4学习笔记(转)
http://blog.csdn.net/21aspnet/article/details/51386557 1.IOC装配Bean 参考[spring实战4 2.2],作者提倡无XML配置化. 1. ...