您的位置:首页 > 其它

POJ 1127 Jack Straws [计算几何]

2016-03-20 10:19 423 查看
2016年9月15日01:09:24更新

使用模板第二

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
using namespace std;
//Template
struct P {
double x, y;
P(double x = 0, double y = 0) : x(x), y(y) {}
void read() {
scanf("%lf%lf", &x, &y);
}
void print() {
printf("%.6f %.6f", x, y);
}
};
typedef P V;
V operator + (V a, V b) {
return V(a.x+b.x, a.y+b.y);
}
V operator - (P a, P b) {
return V(a.x-b.x, a.y-b.y);
}
V operator * (V a, double p) {
return V(a.x*p, a.y*p);
}
V operator / (V a, double p) {
return V(a.x/p, a.y/p);
}
const double eps = 1e-10;
int dcmp(double x) {
if (abs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
bool operator == (P a, P b) {
return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
}
double operator * (V a, V b) {
return a.x*b.x + a.y*b.y;
}
double norm(V a) {
return sqrt(a*a);
}
double det(V a, V b) {
return a.x*b.y - a.y*b.x;
}
double angle(V a, V b) {
return acos(a*b / norm(a) / norm(b));
}
V rotate(V a, double rad) {
return V(a.x*cos(rad) - a.y*sin(rad), a.x*sin(rad)+a.y*cos(rad));
}
//
P getLineIntersection(P p, V v, P q, V w) {
V u = p - q;
double t = det(w, u) / det(v, w);
return p + v*t;
}
double ccw(P a, P b, P c)
{
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
bool isParallel(P a1, P a2, P b1, P b2) {
return dcmp(det(a1 - a2, b1 - b2)) == 0;
}
bool intersects(P a1, P a2, P b1, P b2)
{
if (ccw(a1, a2, b1) * ccw(a1, a2, b2) > 0) return false;
if (ccw(b1, b2, a1) * ccw(b1, b2, a2) > 0) return false;
return true;
}
bool onSeg(P q, P p1, P p2) {
return dcmp(det(p1 - q, p2 - q)) == 0 && (p1 - q)*(p2 - q) <= 0;
}
bool isIntersect(P p1,P p2,P q1,P q2)
{
if(max(p1.x,p2.x)<min(q1.x,q2.x)||max(q1.x,q2.x)<min(p1.x,p2.x)||max(p1.y,p2.y)<min(q1.y,q2.y)||max(q1.y,q2.y)<min(p1.y,p2.y))
return 0;
if(ccw(q1,q2,p1)*ccw
4000
(q1,q2,p2)<=0&&ccw(p1,p2,q1)*ccw(p1,p2,q2)<=0)
return 1;
else
return 0;
}
//MAIN
const int MAXN = 13;
int n;
P p[MAXN], q[MAXN];
bool g[MAXN][MAXN];
void solve()
{
for (int i = 0; i < n; i++) {
p[i].read();
q[i].read();
}
memset(g, 0, sizeof(g));
for (int i = 0; i < n; i++) {
g[i][i] = true;
for (int j = 0; j < i; j++) {
if (isIntersect(p[i], q[i], p[j], q[j])) {
g[i][j] = true;
g[j][i] = true;
}
}
}
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
g[i][j] |= (g[i][k] && g[k][j]);
}
}
}
for (int i = 0; ; i++) {
int a, b;
scanf("%d%d", &a, &b);
if (a == 0 && b == 0) break;
puts(g[a-1][b-1] ? "CONNECTED" : "NOT CONNECTED");
}
}
int main() {
//freopen("in.txt", "r", stdin);
for (;;) {
scanf("%d", &n);
if (n == 0) break;
solve();
}
}


Description

给n个线段,再个m个查询,问两个线段是否相连

reference

《挑战程序设计竞赛(第二版)》

Code

#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;

const int maxn = 13;
const int maxm = 200;
const double eps = 1e-10;

int n;
//考虑误差的加法
double add(const double &a, const double &b)
{
if (abs(a + b) < eps * (abs(a) + abs(b))) return 0;
return a + b;
}

struct P
{
double x, y;
//两个构造函数 必须都写
P() {}
P(double x, double y) : x(x), y(y) {}
//向量加法
P operator + (P p)
{
return P(add(x, p.x), add(y, p.y));
}
//向量减法
P operator - (P p)
{
return P(add(x, -p.x), add(y, -p.y));
}
//向量数乘
P operator * (double d)
{
return P(x * d, y * d);
}
//向量 dot x1*x2+y1*y2
double dot(P p)
{
return add(x * p.x, y * p.y);
}
//向量 det x1y2-x2y1
double det(P p)
{
return add(x * p.y, -y * p.x);
}
};
//判断点p是否在 线段p1-p2上
bool on_seg(P p1, P p2, P q)
{
return (p1 - q).det(p2 - q) == 0 && (p1 - q).dot(p2 - q) <= 0;
}
//求交点
P intersection(P p1, P p2, P q1, P q2)
{
return p1 + (p2 - p1) * ((q2 - q1).det(q1 - p1) / (q2 - q1).det(p2 - p1));
}

void solve()
{
P p[maxn], q[maxn];
for (int i = 0; i < n; i++)
{
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
p[i].x = x1;
p[i].y = y1;
q[i].x = x2;
q[i].y = y2;
}
bool g[maxn][maxn] = {false};
for (int i = 0; i < n; i++)
{
g[i][i] = true;
for (int j = 0; j < i; j++)
//如果平行
if ((p[i] - q[i]).det(p[j] - q[j]) == 0)
g[i][j] = g[j][i] = on_seg(p[i], q[i], p[j])
|| on_seg(p[i], q[i], q[j])
|| on_seg(p[j], q[j], p[i])
|| on_seg(p[j], q[j], q[i]);
else
{
//求交点
P r = intersection(p[i], q[i], p[j], q[j]);
g[i][j] = g[j][i] = on_seg(p[i], q[i], r) && on_seg(p[j], q[j], r);
}
}
//判断是否相连
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
g[i][j] |= g[i][k] && g[k][j];
for (int i = 0; ; i++)
{
int a, b;
scanf("%d%d", &a, &b);
if (a == 0 && b == 0) break;
puts(g[a-1][b-1] ? "CONNECTED" : "NOT CONNECTED");
}
}

int main()
{
for(;;)
{
scanf("%d", &n);
if (n == 0) break;
solve();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: