2021.5.22 訓練賽題解
0. 注
- 本題解的所有圖片和註明內容都可以在 配套檔案 之中獲得。
- 所有程式碼精簡,略去了不重要的部分。
- 部分題目等待更新。
T1.小球
Problem
Solution
...
Code
...
T2.金幣二
Problem
Solution
...
Code
...
T3.繩子
Problem
Solution
觀察題面,是一道明顯的幾何題。最簡單的思想就是模擬,直接去一段一段地求,可這樣難免碼量過大,考慮有沒有簡便方法。
從樣例入手,可畫出圖如下 :
(注 : 配套檔案中既有圖示,也有原使用 GeoGebra 製作的 .ggb 檔案)
我們需要用一根繩子把它繞起來,無非就是找一個能覆蓋住它的最小周長的多邊形。
顯然,在四角,最佳方案就是沿著圓弧。
而在其餘部分,根據兩點之間線段最短,易得最短為連線,即圖中所示線段 EG,FJ,IK,HL。
那這個多邊形實質上就是一個圓角多邊形
周長可以分為兩部分 : 弧與邊。
弧四條剛好可以拼成一個整圓,即 \(2\pi R\)。
而邊的部分簡單觀察就可以發現,等於多邊形周長。
分開計算並加和即可、
注 : 這裡是人為地將每個圓分成了 \(4\) 個圓心角為 \(90^{\circ}\) 的扇形。
Code
const double pi=3.1415926; struct information{ double x; double y; }a[110]; //結構體直接儲存每一個點的座標 (x,y) signed main(){ int n; double r; read(n);scanf("%lf",&r); for(int i=1;i<=n;i++) scanf("%lf %lf",&a[i].x,&a[i].y); double c1=2*pi*r; //周圍 4 段圓弧構成一個整圓的周長 double c2=sqrt((a[n].x-a[1].x)*(a[n].x-a[1].x)+(a[n].y-a[1].y)*(a[n].y-a[1].y)); //預處理出 a[n] 與 a[1] 間距離,方便下方迴圈 for(int i=1;i<=n-1;i++) c2=c2+sqrt((a[i].x-a[i+1].x)*(a[i].x-a[i+1].x)+(a[i].y-a[i+1].y)*(a[i].y-a[i+1].y)); //計算出除 a[n] 與 a[1] 間距離的周長 printf("%.2lf",c1+c2); return 0; }
T4.比賽
Problem
Solution
...
Code
...
T5.中位數概率
Problem
Solution
顯然,這是一道數學題,最簡單的方法推公式
迴歸題目,任取 \(3\) 個數求中位數是 \(k\) 的概率是多少。
中位數是由 \(3\) 個數排序而來的,所以在這之中,一定會有 \(1\) 個 \(k\),這是突破口。
另外兩個數取值也頗有講究,設 \(a,b\) 為任取的數,\(a<k,b>k\)
則只有以下幾種情況是合法的
- \(k\) \(k\) \(k\)
- \(a\) \(k\) \(k\)
- \(b\) \(k\) \(k\)
- \(a\) \(b\)
注意: 這裡僅表示取數的情況,不包括排序,即暫時視作無順序的,來列舉所有情況
而考慮順序(顯然選數有先後順序),有 \(1+3+3+6=13\) 種情況,將這 \(13\) 種情況枚舉出來,把其概率用 \(n\) 和 \(k\) 表示,相加就會有最終的公式。
(樣例 1 與樣例 2 的取數情況不做展示,檔案中有,可自行檢視)
不難發現,在 \(n\) 個數中取到一個 \(a\) 和一個 \(b\) 的概率分別是 \(\dfrac{k-1}{n}\) 和 \(\dfrac{n-k}{n}\) ,於是我們有下面這一張表 :
- 取到 \(k\)
- 取到比 \(k\) 大
- 取到比 \(k\) 小 概率 \(\dfrac{(n-k)(k-1)}{n^3}\)
- 取到 \(k\) 概率 \(\dfrac{n-k}{n^3}\)
- 取到比 \(k\) 小
- 取到 \(k\) 概率 \(\dfrac{k-1}{n^3}\)
- 取到比 \(k\) 大 概率 \(\dfrac{(n-k)(k-1)}{n^3}\)
- 取到 \(k\)
- 取到 \(k\) \(\dfrac{1}{n^3}\)
- 取到比 \(k\) 大 概率 \(\dfrac{n-k}{n^3}\)
- 取到比 \(k\) 小 概率 \(\dfrac{k-1}{n^3}\)
- 取到比 \(k\) 大
- 取到比 \(k\) 小
- 取到 \(k\)
- 取到 \(k\) 概率 \(\dfrac{k-1}{n^3}\)
- 取到比 \(k\) 大 概率 \(\dfrac{(n-k)(k-1)}{n^3}\)
- 取到比 \(k\) 大
- 取到 \(k\) 概率 \(\dfrac{(n-k)(k-1)}{n^3}\)
- 取到 \(k\)
- 取到比 \(k\) 大
- 取到 \(k\)
- 取到 \(k\) 概率 \(\dfrac{n-k}{n^3}\)
- 取到比 \(k\) 小 概率 \(\dfrac{(n-k)(k-1)}{n^3}\)
- 取到比 \(k\) 小
- 取到 \(k\) 概率 \(\dfrac{(n-k)(k-1)}{n^3}\)
- 取到 \(k\)
(注 : 可在檔案"T5 k取數分析.md"中獲得)
將所有概率相加,可得總概率為 \(6(n-k)(k-1)+3n-2\)(化簡不化簡均可),直接帶入求值即可。
注意 : 資料型別與範圍的選擇,double 可以達到 \(10^{15}\),比同是 \(64\) 位的 long long 大很多
Code
signed main(){
int n,k;
read(n);read(k);
double a=1.0*6*(n-k)*(k-1)+3*n-2;
printf("%.10lf",a/n/n/n);
return 0;
}
signed main(){
int n,k;
read(n);read(k);
double a=1.0*6*n*k-6*k*k+6*k-3*n-2;
printf("%.10lf",a/n/n/n);
return 0;
}
T6.上臺階進階版
Problem
Solution
典型的一道斐波那契數列的拓展問題。
資料範圍很小,直接遞推即可。
令 \(f[i]\) 代表到底第 \(i\) 級臺階的方案數。
顯然有 \(f[i]=f[i-1]+f[i-2]+f[i-3]\ (i>3)\)
注意初始化 \(f[1],f[2],f[3]\) ,其餘遞推即可。
Code
int ff[30];
inline int f(int n){
for(int i=1;i<=n;i++) ff[i]=max(ff[i],ff[i-1]+ff[i-2]+ff[i-3]);
return ff[n];
}
signed main(){
int n;
ff[1]=1;ff[2]=2;ff[3]=4;
for(int i=1;;i++){
read(n);
if(n==0) return 0;
printf("%d\n",f(n));
}
return 0;
}
(注 : 配套檔案中有 \(n\in(0,20)\) 的全部資料,可自行檢視。)