计蒜之道 初赛 第三场--腾讯手机地图

题目大意是:

在坐标系里给你n个扇形的半径、起始,结束度数,计算扇形覆盖的面积。

如图:

(因为现在无法提交了,所以无法验证代码,若有错的地方请指正)

这题首先要做的是对边的度数排序,不过是对所有度数排序,最开始想的时候只对扇形开始边的那个度数排序,写了半天一堆if else,后来突然想到了用所有边的度数排序。

首先需要对输进去每每条边度数进行处理,我用的是这个结构体

struct DU
{
	int du;//度数
	int r;//当前度数所对应的半径
	bool if_end;//是否为扇形的结束边
	int num;//扇形编号
}a[MAX];

进行面积计算首先对a[]进行排序,接下来需要用到一些变量:

一个set集合,记录扇形的半径;

一个标记变量R,记录当前已有半径中最大的那个;

记录起始,结束边的度数变量start,end;

面积s;

struct SET_R
{
	int r;//半径
	int num;//半径对应的扇形
	 bool operator < (const dd &a) const
     {
		 return du<=a.du;
     }
};
set<SET_R> set_r;// 记录扇形的半径
set<SET_R>::iterator it;
int R;// 当前已有半径中最大的那个,即set_r.begin()
int start,end;// 起始,结束边的度数变量start,end
int s;
SET_R temp;

下面循环计算面积

从小到大扫描边的度数:

1. set_r 不为空:

当前边半径r>=R,更新end,计算从start到end的面积,更新start;

否则,更新start;

2. 更新set_r,遇到起始边把半径加入set_r,更新R;遇到结束边把此边对应半径从set_r删除,更新R

for(i=0;i<n;i++)
{
	if(set_r.empty()==false )
	{
		if(R<=a[i].r )//如果当前边的半径r>=R
		{
			end=a[i].du;//更新end
			s+=(end-start)*R*R*PI/360;//计算面积,注意需要对减法处理一下
			start=end;//更新start
		}
	}
	else
	{
		start=a[i].du;
	}

	//更新set_r
	temp.r=a[i].r;
	temp.num=a[i],num;
	if(a[i].if_end==false)
	{
		set_r.insert(temp);
	}
	else
	{
		set_r.erase(temp);
	}
	//更新R
	if(set_r.empty()==false)
	{
		it=set_r.begin();
		R=(*it).r;
	}
}

下面就以实际的例子来说明吧,这个例子包含了所有可能的情况。

比如给的扇形是:

10 10 120

25 20 40

25 80 100

20 30 90

5 70 150

如图

对这组数进行整理后得到如下数组 (红色为结束边)


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

扫描[0]

1


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

因为Set_r为空

所以start=a[i].du

2

更新set_r


set_r


10


 


 


 


 


 

R=10;

扫描[1]

1


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

因为R<= a[i].r && set_r不空

所以end=a[i].du

S+=(end-start)*R*R*PI/360; //计算面积,注意需要对减法处理一下

Start=a[i].du

2

更新set_r


set_r


25


10


 


 


 


 


 

R=25;

计算得到蓝色部分面积

扫描[2]

1


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

因为R>a[i].r ,跳过

2

更新set_r


set_r


25


20


10


 


 


 


 


 

R=25;

扫描[3]

1


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

因为R<= a[i].r && set_r不空

所以end=a[i].du

S+=(end-start)*R*R*PI/360; //计算面积,注意需要对减法处理一下

Start=end

2

更新set_r


set_r


20


10


 


 


 


 


 

R=20;

计算得到蓝色部分面积

扫描[4]

1


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

因为R> a[i].r ,跳过

2

更新set_r


set_r


20


10


5


 


 


 


 


 

R=20

扫描[5]

1


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

因为R<= a[i].r && set_r不空

所以end=a[i].du

S+=(end-start)*R*R*PI/360; //计算面积,注意需要对减法处理一下

Start=end

2

更新set_r


set_r


25


20


10


5


 


 


 


 

R=25;

计算得到蓝色部分面积

扫描[6]

1


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

因为R>a[i].r ,跳过

2

更新set_r


set_r


25


10


5


 


 


 


 


 

扫描[7]

1


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

因为R<= a[i].r && set_r不空

所以end=a[i].du

S+=(end-start)*R*R*PI/360; //计算面积,注意需要对减法处理一下

Start=end

2

更新set_r


set_r


10


5


 


 


 


 


 

R=10;

计算得到蓝色部分面积

扫描[8]

1


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

因为R<= a[i].r && set_r不空

所以end=a[i].du

S+=(end-start)*R*R*PI/360; //计算面积,注意需要对减法处理一下

Start=end

2

更新set_r


set_r


5


 


 


 


 


 

R=5;

计算得到蓝色部分面积

扫描[9]

1


0


1


2


3


4


5


6


7


8


9


度数


10


20


30


40


70


80


90


100


120


150


半径


10


25


20


25


5


25


20


25


10


5

因为R<= a[i].r && set_r不空

所以end=a[i].du

S+=(end-start)*R*R*PI/360; //计算面积,注意需要对减法处理一下

Start=end

2

更新set_r


set_r


 


 


 


 


 

计算得到蓝色部分面积

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-16 05:02:16

计蒜之道 初赛 第三场--腾讯手机地图的相关文章

计蒜之道2015程序设计大赛初赛第三场——腾讯手机地图

计蒜之道2015程序设计大赛初赛第三场——腾讯手机地图 (一)题面 腾讯手机地图的定位功能用到了用户手机的多种信号,这其中有的信号的作用范围近,有的信号作用的范围则远一些.有的信号相对于用户在不同的方位强度是不同的,有的则是在任何一个方向上信号强度都一致的. 已知用户面向北方拿着自己的手机,在不同方位的各种信号覆盖区域可以被抽象成以用户为圆心的一系列扇形.已知每个扇形的半径 r,和每个扇形的两条边相对于正东方向的夹角度数.每个信号覆盖区域抽象出的扇形都可以通过从第一条边逆时针旋转到第二条边画出.

计蒜之道 初赛 第三场 题解

腾讯手机地图 腾讯手机地图的定位功能用到了用户手机的多种信号,这其中有的信号的作用范围近,有的信号作用的范围则远一些.有的信号相对于用户在不同的方位强度是不同的,有的则是在任何一个方向上信号强度都一致的. 已知用户面向北方拿着自己的手机,在不同方位的各种信号覆盖区域可以被抽象成以用户为圆心的一系列扇形.已知每个扇形的半径 r,和每个扇形的两条边相对于正东方向的夹角度数.每个信号覆盖区域抽象出的扇形都可以通过从第一条边逆时针旋转到第二条边画出. <img src="http://res.ji

2018 计蒜之道 初赛 第三场

A. 贝壳找房性价比 题解:按s排序后,斜率最大的点必定在相邻的两点之间. #pragma warning(disable:4996) #include<queue> #include<map> #include<string> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #de

2017 计蒜之道 初赛 第三场 D. 腾讯狼人杀 (点边都带权的最大密度子图)

点边都带权的最大密度子图,且会有必须选的点. 写到一半没保存实验室断电,气炸.明天补详细题解. #include<bits/stdc++.h> using namespace std; const double eps = 1e-7; const int INF = 0x3f3f3f3f; const int MAXN= 405;//点数的最大值 const int MAXM= 1e6 + 10;//边数的最大值 #define captype double struct Edge{ int

2017 计蒜之道 初赛 第五场 UCloud 的安全秘钥(中等)

每个 UCloud 用户会构造一个由数字序列组成的秘钥,用于对服务器进行各种操作.作为一家安全可信的云计算平台,秘钥的安全性至关重要.因此,UCloud 每年会对用户的秘钥进行安全性评估,具体的评估方法如下: 首先,定义两个由数字序列组成的秘钥 aa 和 bb近似匹配(\approx≈) 的关系.aa 和 bb 近似匹配当且仅当同时满足以下两个条件: |a|=|b|∣a∣=∣b∣,即 aa 串和 bb 串长度相等. 对于每种数字 cc,cc 在 aa 中出现的次数等于cc 在 bb 中出现的次数

2018 计蒜之道 初赛 第五场

这次的比赛没有现场打,而是等到了今天才来补. 主要是因为那时候和HHHOJ上的比赛冲突了,所以就没写. 这次前三题的难度都比较低,但是就是一个T4要莫比乌斯反演.又是不可食用的. 好了我们开始看题. A. 贝壳找房搬家 这道题刚开始看的时候没看懂题意,觉得T1就是这种立体几何的题目,有种想死的感觉. 因为我认为这个方块可以不规则地想怎么放就怎么放的,其实题目中有一句话: 我们可以把这堆箱子看成一个\(x \times y \times z\) 的长方体. 什么?刚开始只能是长方体吗?好吧好像还是

2017 计蒜之道 初赛 第五场 D. UCloud 的安全秘钥(困难)

小数据打表,大数据暴力. 导致超时的主要原因是$m$小的询问次数太多,可以把$m≤10$的答案直接暴力打表存起来,$m>10$的用$C$题的方法即可. #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <vector> #include <queue> #in

2017 计蒜之道 初赛 第五场 B. UCloud 的安全秘钥(简单)

暴力. 暴力枚举$S$串的每一个长度为$m$的子串,排序判断即可. #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #inc

2017 计蒜之道 初赛 第五场 C. UCloud 的安全秘钥(中等)

暴力. $O(m*n)$的算法可以通过此题,每次询问$O(m)$扫S数组,统计不同数字的个数,每次移动最多只会变化两个数字,如果不同数字个数为$0$,那么答案加$1$. #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <vector> #include <queue&g