計蒜之道 初賽 第三場--騰訊手機地圖 題解

題目大意是:

在座標系裏給你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

 

 

 

 

 

 

 

 

 

 

 

 

計算得到藍色部分面積











發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章