hihor日記 hiho一下 第五十九周

2021-09-05 09:40:46 字數 3332 閱讀 8888

給定乙個單執行緒程式執行的記錄,包含有每個函式啟動和結束的時間。判定該份記錄是否錯誤,主要的錯誤包含:

記錄中的時間不是嚴格遞增的

乙個函式的結束時間比啟動時間更早

記錄中乙個函式有不對應的啟動操作start或結束操作end,比如出現了start卻沒有對應的end,或出現了end卻沒有出現start。而函式的start和end應該成對出現

兩個函式出現交叉的情況,而在單執行緒程式中是不會出現的,比如 a start b start a end b end

演算法分析

根據上面對可能出現錯誤的分析,我們可以分別對每一種錯誤進行處理:

記錄中的時間不是單調遞增的

對每一條記錄的時間都與前一條的時間進行比較即可判定。

乙個函式的結束時間比啟動時間更早

對出現的start和end標記的時間直接進行計算即可判定。

不對應的start和end

統計每個函式start和end的個數是否相等即可判定

兩個函式出現交叉

本題要做的是模擬乙個函式呼叫棧,其實際考察的內容是對於棧的理解和運用。

我們將函式啟動的操作視為進棧push,函式結束的操作視為出棧pop,對於乙個單執行緒的程式來說,其函式的呼叫一定滿足棧的過程。在出現函式a中呼叫函式b的情況時,函式b的結束時間一定早於函式a。這正是棧過程中先進後出原則的體現。

如果我們用棧來模擬前面的例子,則有

a start

stack a

b start

stack a b

a end

此時出現了錯誤,其操作為不在棧頂的a出棧。

對於正確的情況,比如:

a start b start b end a end

同樣用棧來模擬時有:

a start

stack a

b start

stack a b

b end

stack a

a end

stack

因此對於第三類錯誤,我們需要在程式中使用棧來模擬整個過程,即可判定是否有出現錯誤。

總結我們使用棧來模擬整個程式呼叫的過程:

首先對於每乙個記錄比較與前一條記錄的時間。

當出現了start操作的函式直接進棧。

當出現了end操作的函式時,判定該函式是否就是棧頂的函式,若不是則表明該記錄有錯誤。同時對於第二類操作中"出現了end卻沒有出現start"的情況也處理了。若出棧元素是棧頂元素時,我們在此時對其時間進行一次檢查,就可以判定第一類錯誤。

當整個過程記錄都使用棧模擬完畢後,我們還需要對當前棧內是否還有元素進行判定。若棧不為空,則出現第二類情況中"出現了start卻沒有對應的end"的情況。

此外在輸出時,題目要求按照函式呼叫樹深度優先的順序依次輸出每乙個函式。在模擬棧的過程中,函式入棧的順序也正是呼叫樹的順序,所以在處理過程中我們使用乙個序列outputlist來記錄函式入棧的順序,並在函式end操作時去更新該函式其執行時間。

其偽**如下:

for i =1.

. n if (i !=

0 and log[i]

.time < log[i -1]

.time)

return "error"

end if

if log[i]

.action ==

"start" then

stack.

push

(log[i]

) outputlist.

push

(log[i]

.funcname)

// 將該函式壓入輸出序列

else

if (stack.size ==

0 or stack.top.funcname != log[i]

.funcname)

return "error"

end if

startlog = stack.

pop(

) if startlog.time > log[i]

.time then

return "error"

end if

settime

(startlog.funcname, log[i]

.time - startlog.time)

// 記錄outputlist中名稱為startlog.funcname的函式的執行時間

end if

end for

結果分析

在實際的比賽中,該題目的通過率為14%。

在選手的程式中主要出現的錯誤有:

由於本題涉及了時間格式,在時間輸入輸出上出現問題,導致時間計算出問題

未判定函式開始時間是否大於結束時間

模擬棧結束後未檢查棧是否為空,很多選手都是因為這個原因而沒有得到100分

一開始想到了用棧模擬遞迴,但是沒想到的是開始時間居然可以等於結束時間,錯了好幾發 -_-|||

還有一句感慨:c++真是乙個物件導向的語言啊

#include

using namespace std;

#define ll long long

const

int mod =

1e9+7;

const

int maxn =

1e5+5;

const

double eps =

0.00000001

;const

int inf =

0x3f3f3f3f

;struct log

voidms(

)void

fms(

)void

print()

};mapint> mp;

string str[maxn]

;log sta[maxn]

, st[maxn]

;int top =

0, cnt =

0, c[maxn]

;bool vis = false;

intmain()

tmp.id = mp[tmp.fname];if

(op ==

"end"

)else vis = true;

}else vis = true;

}else

else vis = true;

}else}}

}if(top) vis = true;

if(vis) cout <<

"incorrect performance log\n"

;else

return0;

}

hiho學習日記 hiho一下 第五十八周

給定字串s,判定s是否存在子串s 滿足 aa abb bcc c 的形式。其中abc為連續的三個字母,且a,b,c的數量相同。原題目中數量相等的連續n n 3 個字母也是可行的,而實際上當n 3時一定包含有n 3的情況。比如 abcd 就包含有 abc 和 bcd 兩個合法子串。最基本的思路為對s的...

hiho一下 第五十八周

給定字串s,判定s是否存在子串s 滿足 aa abb bcc c 的形式。其中abc為連續的三個字母,且a,b,c的數量相同。原題目中數量相等的連續n n 3 個字母也是可行的,而實際上當n 3時一定包含有n 3的情況。比如 abcd 就包含有 abc 和 bcd 兩個合法子串。最基本的思路為對s的...

hiho一下 第二週

題目名稱 trie樹 小hi和小ho是一對好朋友,出生在資訊化社會的他們對程式設計產生了莫大的興趣,他們約定好互相幫助,在程式設計的學習道路上一同前進。這一天,他們遇到了一本詞典,於是小hi就向小ho提出了那個經典的問題 小ho,你能不能對於每乙個我給出的字串,都在這個詞典裡面找到以這個字串開頭的所...