[洛谷 P3788] 幽幽子吃西瓜
妖夢費了好大的勁為幽幽子準備了一個大西瓜,甚至和兔子鈴仙打了一架。現在妖夢閑來無事,就蹲在一旁看幽幽子吃西瓜。西瓜可以看作一個標準的球體,瓜皮是綠色的,瓜瓤是紅色的,瓜皮的厚度可視為0。妖夢恰好以正視的角度看著這個西瓜。幽幽子是一個吃貨,妖夢一走神,自己背后的刀就不見了,而西瓜也被切掉了一塊。幽幽子切西瓜時刀面始終垂直于桌面,并且切下的一塊在俯視圖中正好是一個以西瓜中心為頂點,半徑為西瓜半徑的扇形。如圖所示,是一種滿足條件的情況
俯視:
正視:
妖夢看著紅紅綠綠的西瓜,忽然陷入思考,紅色的西瓜瓤占整個西瓜可視面積的百分之多少呢?但她對幾何一竅不通,于是想問問幽幽子,但幽幽子正抱著切下來的西瓜大吃特吃,沒有理會妖夢。于是她想讓你來幫她解決這個問題。
為了方便描述問題,我們為俯視圖建立一個平面極坐標系,極點在俯視圖圓形(扇形)的正中央,極軸方向豎直向下。極軸所對應的角度為0度,角度逆時針依次增加,直到轉一圈又回到極軸。因此角度范圍是[0,360)。幽幽子會切掉西瓜從a°到b°的這一整塊。
輸入輸出格式
輸入格式:
?
第一行一個整數T,表示數據組數。
接下來T行每行兩個整數a,b。表示切掉范圍的起始角度和終止角度。若a>b,則切掉的角度為[a,360)∪[0,b]這一范圍。
?
輸出格式:
?
T行,每行一個實數后跟一個百分號“%”,表示被切掉一部分的西瓜的正視圖(平行投影)中,紅色的西瓜瓤占西瓜總可視面積的百分比。在此題中,妖夢的視野方向平行于俯視圖的極軸,并且極軸射線指向妖夢。
輸出的實數四舍五入保留一位小數,你的答案被判作正確,當且僅當與標準答案完全相同。
?
輸入輸出樣例
輸入樣例#1:2 90 270 315 45 輸出樣例#1:
0.0% 70.7%
說明
樣例說明:
第一個樣例中,切掉的西瓜恰好在背面,在妖夢的角度看起來與未切過的西瓜并無區別,因此輸出0%。第二個樣例中,切掉了從315°~45°這一部分,經過計算,得到答案為sqrt(2)/2,化成小數得到0.707,即70.7%
本題目共有10個測試點。
對于第1個測試點,a,b∈{0,90,180,270}。
對于第2個測試點,270<=a<=359,0<=b<=90。
對于第3,4個測試點,180<=a<=359,0<=b<=179。
對于全部測試點,0<=a,b<=359,a≠b。
1<=T<=10000
?
PS:本題實在太玄。。。
首先,要看懂題目的意思,題目就是說給你一個西瓜,給出俯視圖,并在俯視圖上向瓜心方向切2刀,每一刀的距離都是瓜的半徑。要你求出,在正視圖中,紅色的面積是正視圖
面積的多少。
出題者很友善地給出了部分特殊情況,那我們一起來分析下:
10%:
由于a,b∈{0,90,180,270},我們可以全用來特判;
20%(10%+10%):
由于270<=a<=359,0<=b<=90,說明正視圖的總面積是π*r*r。那么,我們只需求出紅色的總面積,具體見下;
40%(10%+10%+20%):
這種情況就開始比較復雜了,可以自己推一下;
100%:
本蒟蒻仍然將每種情況都推了一遍。。。唯一要注意的是,一定要把目光放在留下來的西瓜上面,見下。
另外的:注意cmath里的sin什么的都是弧度,我們要把角度轉成弧度再用,弧度=π*角度/180°。
?代碼如下:
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const double pi=3.14159265358980; 7 inline int read(){ 8 int x=0; char ch=getchar(); 9 while (ch<'0'||ch>'9') ch=getchar(); 10 while (ch>='0'&ch<='9') x=x*10+ch-'0',ch=getchar(); 11 return x; 12 } 13 double chg(int x){ 14 return pi*x/180; 15 } 16 void situ1(int d1,int d2){ 17 if (d1==0||d2==0){ 18 if (d1==0){if (d2==90) puts("50.0%"); else puts("0.0%");} 19 else{if (d1==270) puts("50.0%"); else puts("0.0%");} 20 }else 21 if (d1==90||d2==90){ 22 if (d1==90) puts("0.0%"); else puts("100.0%"); 23 }else 24 if (d1==180||d2==180){ 25 if (d1==180) puts("0.0%"); else puts("100.0%"); 26 } 27 } 28 void situ2(int d1,int d2){ 29 double del=chg(360-d1),ret=sin(del); 30 del=chg(d2),ret+=sin(del),ret*=100/2; 31 printf("%.1f%c\n",ret,'%'); 32 } 33 void situ3(int d1,int d2){ 34 if (d1<=270&&d2>=90) puts("100.0%"); 35 else{ 36 double del=chg(90-abs(270-d1)),ret=0,tot=0; if (d1!=180) ret=sin(del); 37 if (d1>=270) tot=1; else tot=ret; 38 del=chg(90-abs(90-d2)),ret+=sin(del); 39 if (d2<=90) tot+=1; else tot+=sin(del); 40 ret=ret/tot*100; 41 printf("%.1f%c\n",ret,'%'); 42 } 43 } 44 void situelse(int d1,int d2){ 45 double del=0,ret=0,tot=0; 46 if (d1<d2){ 47 if (0<=d1&&d1<90){ 48 if (90-d1<=d2-90) puts("0.0%"); 49 else{ 50 if (d2<=90) del=chg(d2),ret=sin(del),tot++; 51 if (d2>90) del=chg(180-d2),tot=ret=sin(del); 52 del=chg(d1),ret-=sin(del),tot++; 53 ret=ret/tot*100; 54 printf("%.1f%c\n",ret,'%'); 55 } 56 }else 57 if (90<=d1&&d1<180) puts("0.0%"); else 58 if (180<=d1&&d1<270){ 59 if (270-d1>=d2-270) puts("0.0%"); 60 else{ 61 del=chg(d1-180),tot=ret=sin(del),tot++; 62 del=chg(360-d2),ret-=sin(del); 63 ret=ret/tot*100; 64 printf("%.1f%c\n",ret,'%'); 65 } 66 }else 67 if (270<=d1&&d1<360){ 68 del=chg(360-d1),ret=sin(del),tot=2; 69 del=chg(360-d2),ret-=sin(del); 70 ret=ret/tot*100; 71 printf("%.1f%c\n",ret,'%'); 72 } 73 }else{ 74 if (0<d1&&d1<=90){ 75 del=chg(d1),tot=sin(del); 76 del=chg(d2),ret=sin(del); 77 ret=ret/tot*100; 78 printf("%.1f%c\n",ret,'%'); 79 }else 80 if (90<d1&&d1<=180){ 81 if (d2>=90) puts("100.0%"); else{ 82 tot=1; 83 del=chg(d2),ret=sin(del); 84 ret=ret/tot*100; 85 printf("%.1f%c\n",ret,'%'); 86 } 87 }else 88 if (180<d1&&d1<=270){ 89 del=chg(d1-180),ret=sin(del),tot++; 90 if (90<=d2) ret=tot=1; 91 if (0<d2&&d2<90) del=chg(d2),ret+=sin(del),tot++; 92 ret=ret/tot*100; 93 printf("%.1f%c\n",ret,'%'); 94 }else 95 if (270<d1&&d1<360){ 96 del=chg(360-d1),ret=sin(del),tot++; 97 if (270<d2) del=chg(360-d2),tot=sin(del); 98 if (90<=d2&&d2<180) del=chg(180-d2),ret+=sin(del),tot+=sin(del); 99 if (0<d2&&d2<90) del=chg(d2),ret+=sin(del),tot++; 100 ret=ret/tot*100; 101 printf("%.1f%c\n",ret,'%'); 102 } 103 } 104 } 105 inline void _solve(){ 106 int dg_s=read(),dg_t=read(); 107 if (dg_s%90==0&&dg_t%90==0) situ1(dg_s,dg_t); else 108 if (270<=dg_s&&dg_s<360&&0<=dg_t&&dg_t<=90) situ2(dg_s,dg_t); else 109 if (180<=dg_s&&dg_s<360&&0<=dg_t&&dg_t<180) situ3(dg_s,dg_t); else 110 situelse(dg_s,dg_t); 111 } 112 int main(){ 113 for (int T=read(); T; T--) _solve(); 114 return 0; 115 } View Code?
轉載于:https://www.cnblogs.com/whc200305/p/7076730.html
總結
以上是生活随笔為你收集整理的[洛谷 P3788] 幽幽子吃西瓜的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html编写监考表,星空监考表智能编排系
- 下一篇: 皮肤范围检测matlab思路,一种基于S