平面切分【第十一届】【省赛】【B组】

看题集页面写着欧拉定理,我还去查了一下欧拉定理,结果也没看懂。

然后看了题解,发现核心思想就是:“每增加一条直线,对平面区域个数增加的贡献值,是其与先前直线的交点数(不包括与已有交点重合的点)+1 (1相当于加了一条不重复直线就会增加一个区域)”。

我们在遍历一条新的直线时,首先判断这条直线是否和之前的直线是重复的,如果重复的,则没有计算的必要。在这一步中去重的功能通过set来实现。

如果这条直线是不重复的,那么我们首先可以把原有的区域数+1,因为一条直线无论在平面上如何摆放,它的出现就会对平面起到一次切割作用。

然后,这条直线可能还与以前的直线有交点,那么每个不重复交点的存在又会催生一次切割,生成一个新的区域。所以思路就出来了。

 

代码如下:

devc++不能用auto,写的我很苦恼,太久没写了,还得去查set怎么迭代。😔

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<cmath>
#include<vector>
#include<set>
#define ll long long
using namespace std;
const int N = 2005;
const int mod = 20201114;
int compute(int k, int b, set<pair<int, int> >& s){
	set<pair<double, double> >d;
	for(set<pair<int, int> >::iterator l = s.begin(); l != s.end(); l++){
		int x = l->first;
		int y = l->second;
		if(x != k){
			int kk = k - x;
			int bb = y - b;
			double xx = (double)bb / kk;  //注意不要写反了
			
			double yy = (double)k * xx + b;
//			cout<<xx<<" "<<yy<<endl;
			d.insert(make_pair(xx, yy));  //交点去重
		}
	}
	return d.size();
}
int main(){
	int n;
	scanf("%d", &n);
	int res = 1;  //注意,从1开始,本来就有一个大区域就是平面本身了
	set<pair<int, int> >s;
	for(int i = 0; i < n; i++){
		int k, b;
		scanf("%d%d", &k, &b);
		int m = s.size();
		s.insert(make_pair(k, b));
		if(s.size() != m){
			res++;  //存在即+1
			res += compute(k, b, s);  //交点贡献的新区域
//			cout<<res<<endl;
		}
	}
	cout<<res<<endl;
	return 0;
} 

到此为止。

借鉴的题解:

蓝桥杯 平面切分(欧拉定理)_江南路漫的博客-CSDN博客

AcWing 2873. 平面切分 - AcWing

昨晚梦见稀里糊涂地去面试,结果是不小心把我勾上的。我死乞白赖地说给我一次机会,结果还是y总面试我。

他说你给我上一门课吧,我说我又不是师范生,我哪会上课?

他说那你给我讲讲质数筛吧,我啊吧啊吧,他说你滚吧!

所以,我还是去买一下y总的每日一题吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值