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 ...
随机推荐
- S7-300过程映像区详解
一.概念 W过程镜像区输入字 PIW立即输入区字 PIW不用等系统刷新,立即读入 IW等待系统刷新后读入 二.PIW/IW,PQW/QW 引用西门子论坛一位大侠的比方加深理解: ...
- 51nod 1433:0和5
1433 0和5 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 取消关注 小K手中有n张牌,每张牌上有一个一位数的数, ...
- sftp 多用户安装与配置
sftp 是 Secure File Transfer Protocol 的缩写,安全文件传送协议.可以为传输文件提供一种安全的加密方法.SFTP 为 SSH 的一部分,由于这种传输方式使用了加密/解 ...
- Windows环境下的32位汇编语言程序设计
一个逆向的告诉我可以尝试学一下8086处理器,再回头看一看自己学过的会有提高学呗,8086处理器怎么学....然后就学了8086的汇编, 好友就分享了琢石成器——Windows环境下的32汇编语言设计 ...
- docker中使用mongodb
连接mongodb容器,下拉alpine应用测试连接
- 洛谷 P1929 迷之阶梯
题目传送门 解题思路: f[i]表示跳到第i层的最少移动次数,如果可以从下面一级跳上来,那么直接跳上来,如果跳不上来,那就往后退,退到不能退或能跳上第i层 AC代码: #include<iost ...
- thinkphp3.2.3 缓存导致getshell终极解决办法
在Application\Runtime目录中创建文件.htaccess <IfModule mod_rewrite.c> deny from all </IfModule>
- VUE- 访问服务器端数据 axios
VUE- 访问服务器端数据 axios 一,安装 npm install axios 二,在http.js中引入 import axios from 'axios'; 三,定义http request ...
- [题解] LuoguP2257 YY的GCD
传送门 给\(n,m\),让你求 \[ \sum\limits_{i=1}^n \sum\limits_{j=1}^m [\gcd(i,j) \in prime] \] 有\(T\)组询问\((T \ ...
- 微信浏览器 UA
mozilla/5.0 (linux; android 5.1.1; mi note pro build/lmy47v) applewebkit/537.36 (khtml, like gecko) ...