链接:https://ac.nowcoder.com/acm/contest/3570/I

来源:牛客网

题目描述

最近ZSC和他的女朋友NULL吵架了。因为ZSC是一个直男,他不知道该怎么办,于是他寻求恋爱之子磊子哥的帮助。“比起磊子,我更需要女朋友”/doge。

矛盾就如一条条线,纠在一起,越来越乱,ZSC和NULL的矛盾可以看作二维直角坐标系,在平面中有N条线段,线段的两个端点的坐标分别是 pi_x,pi_y和qi_x,qi_y。当两个线段有至少一个公共点时,就认为它们是相连的。事情往往都有关联,所以通过相连的线段连在一起的两条线段也是相连的。

恋爱之子磊子哥每次祈祷都可以消除一条线段以及所有与它相连的线段,自从磊子哥成为恋爱之子后特别忙,现在他向你求助“那你能帮帮我吗,我想知道我最少要祈祷几次才能消除所有线段”。学过算法的你,能帮助磊子哥求出最少的次数吗?

输入描述:

输入第一行是一个整数N(1≤N≤4∗103),表示线段的个数,接下来N行,每行四个整数pi_x,pi_y和qi_x,qi_y表示该线段的两个端点坐标。

输出描述: 输出最少需要的祈祷数。

示例1
输入 复制
4
0 0 6 0
6 -4 6 4
0 4 4 4
2 2 2 6
输出
2

说明

示例2
输入 复制
3
0 1 1 0
0 2 2 0
0 3 3 0
输出 复制
3
说明

示例3
输入 复制
29
1 8 2 9
2 9 11 9
11 9 9 8
9 8 1 8
1 6 2 7
2 7 2 8
3 6 5 8
5 6 6 7
6 7 6 8
7 6 9 8
7 7 8 8
1 3 1 5
1 5 3 5
3 5 3 3
3 3 1 3
2 1 2 3
0 2 2 2
2 2 4 2
1 -1 2 1
3 -1 2 1
5 3 5 5
5 5 7 5
7 5 7 3
7 3 5 3
6 1 6 3
4 2 6 2
6 2 8 2
5 -1 6 1
7 -1 6 1
输出 复制
2

说明

思路如下

题意:题目给出 n 条直线的端点,通过每次次的祈祷,可以把其中相交的线段都去掉,问我们需要祈祷多少次才可以,把所有线段都消除,那么我们就要考虑两个问题:怎么判断直线相交、怎么一次把所有相交的直线都消去。对于前一个问题我也没看懂到大佬的题解,但对于第二个问题,我们可以明确的看出可以并查集来解决,通过判断线段相交,把所有的相交的线段视为一个集合,这样有几个集合我们就需要祈祷 几次

并查集总结传送门

题解如下(贴出大佬的代码一起共赏)

#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define db double
#define gcd __gcd
#define pb push_back
#define lowbit(x) (x & (-x))
#define PII pair<int, int>
#define all(x) x.begin(), x.end()
#define debug(x) cout << #x << " = " << x << endl
#define rep(i, a, b) for(__typeof(b) i = a; i <= (b); i++)
#define Rep(i, a, b) for(__typeof(a) i = a; i >= (b); i--)
#define Mod(a,b) a<b?a:a%b+b
template<class T> inline T qmin(T a, T b) { return a < b ? a : b; }
template<class T> inline T qmax(T a, T b) { return a > b ? a : b; }
typedef long long ll;
typedef unsigned long long ull;
const db PI = acos(-1);
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 1;
const int maxn = (int)1e5 + 5;//remember to modify it, No RE&nbs***bsp;MLE
const ll INF = 0x3f3f3f3f3f3f3f3f;
using namespace std;
#define cross(p1, p2, p3) ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y))
#define cross0p(p1, p2, p3) sign(cross(p1,p2,p3))
const db eps = 1e-9;
inline int sign(db a) { return a < -eps ? -1: a > eps; }
inline int cmp(db a, db b) { return sign(a-b); }
struct P{
db x, y;
P() {}
P(db _x, db _y): x(_x), y(_y) {}
P operator+(P p) { return {x + p.x, y + p.y}; }
P operator-(P p) { return {x - p.x, y - p.y}; }
P operator*(db d) { return {x * d, y * d}; }
P operator/(db d) { return {x / d, y / d}; }
bool operator<(P p)const {
int c = cmp(x, p.x);
if(c) return c == -1;
return cmp(y, p.y) == -1;
}
bool operator==(P o) const {
return cmp(x, o.x) == 0 && cmp(y, o.y) == 0;
}
db distTo(P p) { return (*this - p).abs(); }
db abs() { return sqrt(abs2()); }
db abs2() { return x * x + y * y; }
db dot(P p) { return x * p.x + y * p.y; }
db det(P p) { return x * p.y - y * p.x; }
};
bool intersect(db l1, db r1, db l2, db r2)
{
if(l1 > r1)swap(l1, r1); if(l2 > r2) swap(l2, r2);
return !( cmp(r1, l2) == -1 || cmp(r2, l1) == -1);
}
bool isSS(P p1, P p2, P q1, P q2){
return intersect(p1.x, p2.x, q1.x, q2.x) && intersect(p1.y, p2.y, q1.y, q2.y) && cross0p(p1, p2, q1) * cross0p(p1, p2, q2) <= 0 && cross0p(q1, q2, p1) * cross0p(q1, q2, p2) <= 0;
}
//并查集开始
int f[maxn];
int find(int x) //递归查找x元素的父节点
{
if(f[x] == x)
return x;
return f[x] = find(f[x]); //注意这里在查找父节点的时候 已经把节点的路径进行了压缩(进行了优化)
}
void Union(int x,int y)
{
int fx = find(x),fy = find(y);
if(fx != fy) f[fx] = fy; //x,y是是有关系的,但是他们的父节点不同所以要 把其中的一个赋接待你作为子节点 拼接到临一个父节点上
} //这样x、 y 就有了相同的父节点,就属于同一个集合了
int main()
{
int n;
P p[10005], q[10005];
scanf("%d", &n);
for(int i = 1 ; i <= n ; i++){
f[i] = i; //并查集元素的初始化
scanf("%lf %lf %lf %lf", &p[i].x, &p[i].y, &q[i].x, &q[i].y);
}
for(int i = 1 ; i <= n ; i++){
for(int j = i + 1 ; j <= n ; j++){
if(isSS(p[i], q[i], p[j], q[j]))Union(i, j);//如果为真i,j 是有关系的,所以他们应该在同一个集合中
}
}
int ans = 0;
for(int i = 1 ; i <= n ; i++)if(f[i] == i)ans++;
printf("%d\n", ans);
return 0;
}

I、恋爱之子的更多相关文章

  1. XXOOJL

    她的鞋子放在外面没拿进来很显眼,我们俩正抱在床上,刚做完什么也没穿,她也没擦.听到门外的脚步声.赶紧穿.她在我房间里没出声,但我父亲肯定看出来了.于是问我:母亲去哪了,然后他去找她. 太尴尬了,那晚我 ...

  2. 【0门槛】PR稿的自我修养

    本文来自网易云社区 作者:巩爽 十一过完,离2018年结束就只剩下85天啦!是不是2016年许下的2017年的梦想,在2018年还没有实现? 做过的项目仿佛都小有成就,可惜只是内部自嗨,想做域外宣传却 ...

  3. 二狗子 、初恋及HTTPS

    最近二狗子宅在老家,最悠闲的就是泡壶茶看着院子的风景发呆一下午.今天,二狗子看到了对面自己暗恋的小翠花,看着美好的小翠花二狗子不禁想起了自己美好的初恋. 二狗子的初恋在初中,那个时候学校禁止带手机.上 ...

  4. 深入理解MySql子查询IN的执行和优化

    IN为什么慢? 在应用程序中使用子查询后,SQL语句的查询性能变得非常糟糕.例如: SELECT driver_id FROM driver where driver_id in (SELECT dr ...

  5. Hawk 6. 高级话题:子流程系统

    子流程的定义 当流程设计的越来越复杂,越来越长时,就难以进行管理了.因此,采用模块化的设计才会更加合理.本节我们介绍子流程的原理和使用. 所谓子流程,就是能先构造出一个流程,然后被其他流程调用.被调用 ...

  6. margin折叠-从子元素margin-top影响父元素引出的问题

    正在做一个手机端电商项目,顶部导航栈的布局是一个div包含一个子div,如果给在正常文档流中的子div一个垂直margin-top,神奇的现象出现了,两父子元素的边距没变,但父div跟着一起往下走了! ...

  7. DevExpress第三方控件使用实例之ASPxPopupControl弹出子窗体

    弹出页面控件:ASPxPopupControl, <dxpc:ASPxPopupControl ID="popubCtr" runat="server" ...

  8. Mysql - 性能优化之子查询

    记得在做项目的时候, 听到过一句话, 尽量不要使用子查询, 那么这一篇就来看一下, 这句话是否是正确的. 那在这之前, 需要介绍一些概念性东西和mysql对语句的大致处理. 当Mysql Server ...

  9. 面向组合子设计Coder

    面向组合子 面向组合子(Combanitor-Oriented),是最近帮我打开新世界大门的一种pattern.缘起haskell,又见monad与ParseC,终于ajoo前辈的几篇文章. 自去年9 ...

随机推荐

  1. 谈谈集合.Queue

    之前说到,Java中集合的主要作用就是装盛其他数据和实现常见的数据结构.所以当我们要用到"栈"."队列"."链表"和"数组&quo ...

  2. Feign 客户端的使用 二

    一.Feign的使用(客户端调用 json/xml格式的接口) 1.服务端接口编写 <parent> <groupId>org.springframework.boot< ...

  3. Java并发编程(02):线程核心机制,基础概念扩展

    本文源码:GitHub·点这里 || GitEE·点这里 一.线程基本机制 1.概念描述 并发编程的特点是:可以将程序划分为多个分离且独立运行的任务,通过线程来驱动这些独立的任务执行,从而提升整体的效 ...

  4. jupyternotebook安装

    本篇阅读目录 一.Jupyter notebook环境安装 二.爬虫介绍 回到顶部 一.Jupyter notebook环境安装 1.Anaconda 以及 安装步骤 Anaconda指的是一个开源的 ...

  5. 2020年IOS超级签最新实现原理详解

    相信2019年最火的应该就是这个东西了,我也是摸着石头过河,勉强混进了这个行业! 超级签这个东西吧,说白了就是用个人账号分发应用,大致分成以下几个步骤吧 一.使用配置文件获取UDID 苹果公司允许开发 ...

  6. 基于.NetCore3.1搭建项目系列 —— 使用Swagger做Api文档 (上篇)

    前言 为什么在开发中,接口文档越来越成为前后端开发人员沟通的枢纽呢? 随着业务的发张,项目越来越多,而对于支撑整个项目架构体系而言,我们对系统业务的水平拆分,垂直分层,让业务系统更加清晰,从而产生一系 ...

  7. Java已五年1—二本物理到前端实习生到Java程序员「回忆贴」

    关键词:郑州 二本 物理专业 先前端实习生 后Java程序员 更多文章收录在码云仓库:https://gitee.com/bingqilinpeishenme/Java-Tutorials 前言 没有 ...

  8. 44. 更改oracle字符集编码american_america.zh16gbk 改为 SIMPLIFIED CHINESE_CHINA.ZHS16GBK

    注册表NLS_LANG值改为SIMPLIFIED CHINESE_CHINA.ZHS16GBK

  9. 原来rollup这么简单之 rollup.watch篇

    大家好,我是小雨小雨,致力于分享有趣的.实用的技术文章. 内容分为翻译和原创,如果有问题,欢迎随时评论或私信,希望和大家一起进步. 大家的支持是我创作的动力. 计划 rollup系列打算一章一章的放出 ...

  10. Linux你不知道的ping操作

    1.指定ping的次数  -c 选项 ping -c 3 www.baidu.com 2.只返回结果  -q  选项 ping -q -c 3 www.baidu.com 3.指定数据包的大小  -s ...