首页 > 其他分享 >P8720 [蓝桥杯 2020 省 B2] 平面切分 题解

P8720 [蓝桥杯 2020 省 B2] 平面切分 题解

时间:2023-02-25 15:44:43浏览次数:49  
标签:直线 P8720 题解 gathered 蓝桥 交点 cr 部分 define

前言

建议本题评黄,因为需要较强的数学能力。
如果格式炸了去这里看哦

题意

给出 \(N\) 条直线的解析式 \(y=kx+b\),求出这些直线把平面分成了几部分。

思路

看到这道题我们会梦回小学五年级在某场考试或某张毒瘤数学试卷里做到的题目:

\[\boxed{\begin{gathered} \color{#FFFFFF}\rule{400pt}{110pt}\cr[-100pt] \begin{gathered}\Large\textbf{** 小学五年级数学拓展试卷}\end{gathered} \cr \underline{\text{114.}}\text{完成以下一道应用题}\kern{250pt}\cr \begin{gathered} \end{gathered} \textcolor{#FFFFFF}{\underline{\kern{280pt}}}\cr \text{\kern{20pt}已知 1 条直线可以把平面最多分成两部分,2 条直线可以把平面最}\cr \text{~多分成 4 部分,3 条最多可以分成 7 部分,请问 4、5 条直线最多可}\cr \text{以把平面分成几部分?\kern{190pt}}\cr \end{gathered}} \]

回忆一下我们当时是如何做出这样的题目的?找规律?画图?蒙答案?

或者我们可以重复这样的步骤。

  • 当没有任何直线时,显然平面只有一部分。
  • 当有 \(1\) 条直线时,平面有 \(2\) 个部分。
  • 当有 \(2\) 条直线时,第 \(2\) 条直线交第 \(1\) 条于一个点,所以增加了 \(2\) 个部分,共 \(4\) 个部分。
  • 当有 \(3\) 条直线时,第 \(3\) 条直线交前两条各于一个点,所以又增加了 \(3\) 个部分,共 \(7\) 个部分 (假设没有三线共点或平行)
  • 当有 \(4\) 条时,增加 \(3\) 个交点,\(4\) 个部分,共 \(11\) 个部分。
  • 当有 \(5\) 条时,增加 \(4\) 个交点,\(5\) 个部分,共 \(16\) 个部分。

以上推断均保证没有三线共点或平行的情况。
仔细阅读加粗部分显然可以发现,每增加 \(n\) 个交点,会多出 \(n+1\) 个部分。
我们就成功的把求几部分的问题转化成了求交点的问题。

接着考虑 三点共线平行 的情况。

对于三点共线,若一条直线于另两条直线的交点交在一起 (注意我的表述方式),因为这一点之前已经分出了它所对应的部分,所以不需要再次统计。
对于一对直线平行,则仅对这两条直线来说,它们没有任何交点,因此这对直线不需要计算交点。

综上所述,我们只要模拟以上过程,不断添加一条一条直线并且计算交点个数即可。

代码

#include <iostream>
#include <set>
#include <vector>

#define i64 long long
#define reg register
#define qwq puts("fzy qwq ~");
#define pb push_back
#define Line pair<double, double>
#define kk first
#define bb second

using namespace std;

int n, tmp, ans = 1;
double xk, xb, k1, k2, b1, b2;
set<Line> l;
vector<int> k, b;

void init()
{
    for (reg int i = 1; i <= n; ++i)
    {
        scanf("%lf%lf", &xk, &xb);
        l.insert(make_pair(xk, xb)); // 使用 set 去重并顺手排序
    }
    for (reg auto x : l)
        k.pb(x.kk), b.pb(x.bb);      // 将直线放回 vector O(1) 访问降低常数
}

int main()
{
    scanf("%d", &n);
    init();
    
    Line p;
    for (reg int i = 0; i < (int)k.size(); ++i) //枚举每一条直线
    {
        set<Line> pos; 							// 交点的集合
        for (reg int j = i - 1; j >= 0; --j)
        {
            k1 = k[i], b1 = b[i],
            k2 = k[j], b2 = b[j];
            if (k1 == k2) continue;				// 平行,直接计算下一条直线
            p.kk = (b2 - b1) / (k1 - k2); 		// 求得交点
            p.bb = k1 * ((b2 - b1) / (k1 - k2)) + b1; // 
            pos.insert(p);
        }
        ans += pos.size() + 1; 					// 添加新分出的部分
    }
    printf("%d\n", ans);
    return 0;
}

标签:直线,P8720,题解,gathered,蓝桥,交点,cr,部分,define
From: https://www.cnblogs.com/YttriumWillow/p/17154550.html

相关文章

  • [六省联考 2017] 组合数问题 题解
    题目描述组合数\(C_n^m\)表示的是从\(n\)个互不相同的物品中选出\(m\)个物品的方案数。举个例子,从\((1,2,3)\)三个物品中选择两个物品可以有\((1,2)\),\((1,......
  • 2.25 校内模拟赛 题解
    好消息:签到题首杀。坏消息:只会签到题。\(\text{contestid:726}\)A.随机\(\text{problemid:2307}\)B.回文路径\(\text{problemid:3772}\)成功首杀。看到回......
  • AtCoder Beginner Contest 282 A-F 题解
    比赛链接A-GeneralizedABC额,对,是的,没错,先这样再那样然后这样就是这样。点击查看代码#include<cstdio>intn;intmain(){ scanf("%d",&n); for(inti=0;......
  • #68. 「NOIP2004」津津的储蓄计划 题解
    #68.「NOIP2004」津津的储蓄计划题解题目传送门题目知识点模拟题目分析非常的“明显”,这是一道模拟题。题意说明有可能在某个月的月初,津津手中的钱加上这个月妈妈......
  • #119. 最大整数 题解
    #119.最大整数题解题目传送门题目知识点字符串+贪心题意说明设有n个正整数(n<=20),将它们连接成一排,组成一个最大的多位整数。(题目简介明了,一看就是出题人懒得写题目背......
  • #160. 「NOIP2004 普及组」不高兴的津津 题解
    #160.「NOIP2004普及组」不高兴的津津题解题目传送门题目知识点枚举题意说明津津如果一天上课超过八个小时就会不高兴,而且上得越久就会越不高兴。假设津津不会因为......
  • #373. 「USACO1.1」Friday the Thirteenth 题解
    #373.「USACO1.1」FridaytheThirteenth题解题目传送门题目知识点模拟+数学闰年知识点题意说明写一个程序来计算在n年里13日落在星期一,星期二......星期日的次数......
  • match 题解
    题面题目描述一个匹配模式是由一些小写字母和问号组成的一个字符串。当一个由小写字母组成的字符串\(s\),长度和匹配模式长度相同,并且在对应的每一位都相等或模式串相应......
  • 题解 Codeforces 1746F Kazaee
    题意给定长度为\(n\)的数组\(a\),和\(q\)次操作,支持:给定\(i,x\),修改\(a_i\)为\(x\)给定\(l,r,k\),查询\([l,r]\)中是否每个数的出现次数都是\(k\)的倍数......
  • 题解 LOJ P2393 「JOISC 2017 Day 2」门票安排
    题意咕咕咕。题解这题太神了,无限膜拜p_b_p_b,搬运一波题解。首先考虑二分。题意等价于选一些区间进行反转。首先注意到反转的区间两两有交,不然不反转一定更优。设反转......