1. 程式人生 > >BiliBili, ACFun… And More!【遞歸算法】

BiliBili, ACFun… And More!【遞歸算法】

double font include main color nbsp image stc class

題源:http://acm.uestc.edu.cn/#/problem/show/3

技術分享圖片

題解:

  題意:播放一段視頻文件,有播放速度和緩沖速度兩種,因為作者的癖好,播放前要緩沖幾秒鐘(這段時間不計算在總時間內),如果當播放文件大小等於緩沖文件大小時,緩沖文件還沒有緩沖完,播放器會從頭開始,但緩沖繼續緩沖。

  總結幾個關鍵點:

    1.當需要重新播放的時候,已經緩沖的大小(這裏的性質等於開始播放前緩沖的大小),此時的情形類似最開始的情況,只是提前緩沖大小不一樣了。

    2.當播放大小等於緩沖大小(這裏列一個方程),判斷緩沖大小是否大於等於總大小,否則重新播放。

  根據關鍵點的信息,可以嗅出遞歸算法的味道,什麽是遞歸算法?

  在數學中,遞歸是X0屬於A集合,f(X0) = f(f(X1)),X0等於在X1對應的因變量。外層需要內層運算的結果

  在編程中,遞歸是函數自己調用自己,但有一個遞歸出口。函數調用實際上是在“棧”中進行,最先調用的函數在棧底。

  網上扣一張圖能很形象理解遞歸(如有侵權立即刪除)

技術分享圖片

回歸正題:

設播放速度為X,緩沖速度為Y,提前播放的時間T,文件總大小Z,需要的時間t,重新播放前一刻的緩沖大小Size。

1.分兩種情況。

  1)網速倍兒棒,一次都沒重新播放過

    t = Z/X

    滿足條件:緩沖速度Y大於等於播放速度X 或者 當要重新播放的時候,緩沖大小大於總大小

         Y >= X || T/(X - Y) >= S/X

  2)令人抓狂的情況,老是重新播放

    t = t1 + t2 + t3 ... + tn;

    tn = Size/(X-Y);//第N次遞歸的播放時間

    遞歸相同式子:緩沖文件大小Size,調用自身函數時,緩沖文件大小變為Size/(X-Y)*X;

    遞歸終止條件:緩沖文件大小大於等於總文件大小S:size / (X - Y)*X >= S

附上代碼:

//C code


#include<stdio.h>

#define M 1000

double Time(double size, int X, int Y, int S);//遞歸函數

int main()
{
	int num,X[M],Y[M],S[M],T[M];//X playspeed播放速度,Y bufferspeed緩沖速度,S totalsize文件總大小
	int i;//循環參數
	scanf("%d", &num);//測試數目
	for (i = 0; i < num; i++)
	{
		scanf("%d %d %d %d", &X[i], &Y[i],&T[i], &S[i]);
	}
	for (i = 0; i < num; i++)
	{
		if (X[i] <= Y[i] || T[i] / (double)(X[i] - Y[i]) >= S[i] / (double)X[i])//網速好
		{
			printf("Case #%d: %.3f\n", i+1, S[i] / (double)X[i]);
		}
		else//辣雞網速
		{
			printf("Case #%d: %.3f\n", i + 1, Time(T[i] * Y[i], X[i], Y[i], S[i]));
		}
	}
    return 0;
}

double Time(double size,int X,int Y,int S)//size是重新播放前一刻的緩沖文件大小,作為遞歸變量
{
	double t = 0;
	if (size / (X - Y)*X < S)//遞歸終止條件
	{
		t = size / (X - Y) + Time(size / (X - Y)*X, X, Y, S);
	}
	else
	{
		t = S / (double)X;
	}
	return t;
}

  

有什麽問題歡迎在留言區交流!

BiliBili, ACFun… And More!【遞歸算法】