1. 程式人生 > 其它 >2021.5.22 訓練賽題解

2021.5.22 訓練賽題解

0. 注

  1. 本題解的所有圖片和註明內容都可以在 配套檔案 之中獲得。
  2. 所有程式碼精簡,略去了不重要的部分。
  3. 部分題目等待更新。

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\)
    \(k\)

注意: 這裡僅表示取數的情況,不包括排序,即暫時視作無順序的,來列舉所有情況
而考慮順序(顯然選數有先後順序),有 \(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\) 概率 \(\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\) 概率 \(\dfrac{n-k}{n^3}\)
      • 取到比 \(k\) 小 概率 \(\dfrac{(n-k)(k-1)}{n^3}\)
    • 取到比 \(k\)
      • 取到 \(k\) 概率 \(\dfrac{(n-k)(k-1)}{n^3}\)

(注 : 可在檔案"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)\) 的全部資料,可自行檢視。)