什么是算法
算法是指解決問題或完成特定任務(wù)的一系列明確指令或步驟集合。它是一個定義良好、逐步執(zhí)行的操作序列,用于將輸入轉(zhuǎn)換為輸出。算法可用于計(jì)算、數(shù)據(jù)處理、自動化控制、問題解決等各個領(lǐng)域。
算法通常由一系列簡單的操作組成,這些操作可以是基本的數(shù)學(xué)運(yùn)算、邏輯判斷、條件分支、循環(huán)控制等。通過組合和重復(fù)執(zhí)行這些操作,算法能夠解決更加復(fù)雜的問題。
在計(jì)算機(jī)科學(xué)中,算法是程序設(shè)計(jì)的基礎(chǔ)。程序員使用算法來描述和實(shí)現(xiàn)解決問題的步驟,從而使計(jì)算機(jī)能夠按照指定的方式執(zhí)行任務(wù)。不同的算法可能會根據(jù)問題的特性和要求產(chǎn)生不同的結(jié)果和效率。
算法的設(shè)計(jì)和分析是計(jì)算機(jī)科學(xué)的核心內(nèi)容之一。好的算法應(yīng)當(dāng)具有正確性、可讀性、高效性和可擴(kuò)展性。算法的性能評估和優(yōu)化是提高計(jì)算效率和解決問題的關(guān)鍵。
在算法比賽中,參賽者需要運(yùn)用各種不同的算法來解決問題。一些常見的算法及其在比賽中的應(yīng)用:
-
貪心算法(Greedy algorithm):貪心算法是一種每次選擇當(dāng)前最優(yōu)解的策略。它通常適用于那些具有最優(yōu)子結(jié)構(gòu)性質(zhì)的問題,每一步的選擇都不會影響后續(xù)步驟的結(jié)果。貪心算法在某些場景下可以高效地找到近似最優(yōu)解,如最小生成樹、任務(wù)調(diào)度等。
-
動態(tài)規(guī)劃(Dynamic programming):動態(tài)規(guī)劃將復(fù)雜問題分解為相互重疊的子問題,并通過存儲子問題的解來避免重復(fù)計(jì)算。它通常適用于具有重疊子問題和最優(yōu)子結(jié)構(gòu)性質(zhì)的問題。動態(tài)規(guī)劃在解決最短路徑、背包問題、字符串匹配等方面有廣泛應(yīng)用。
-
回溯法(Backtracking):回溯法是一種通過遞歸地嘗試所有可能的解空間來求解問題的方法。它在搜索問題、組合問題、迷宮問題等方面表現(xiàn)出色。回溯法通過深度優(yōu)先搜索來窮舉解空間,同時利用剪枝技術(shù)減少不必要的搜索。
-
分治法(Divide and Conquer):分治法將問題劃分為獨(dú)立的子問題,然后遞歸地解決每個子問題,并合并子問題的解來得到最終的解。它在排序算法(如快速排序、歸并排序)、查找問題(如二分查找)以及一些優(yōu)化問題中廣泛使用。
-
圖算法:圖算法用于解決與圖相關(guān)的問題,如最短路徑(Dijkstra算法、Floyd-Warshall算法)、最小生成樹(Prim算法、Kruskal算法)、拓?fù)渑判?、圖染色等。
此外,還有許多其他的經(jīng)典算法和數(shù)據(jù)結(jié)構(gòu),如排序算法(冒泡排序、插入排序、堆排序)、搜索算法(深度優(yōu)先搜索、廣度優(yōu)先搜索)、字符串匹配算法(KMP算法、Boyer-Moore算法)等,在算法比賽中都可能被使用。參賽者需要根據(jù)問題的特點(diǎn)選擇合適的算法,并進(jìn)行優(yōu)化以達(dá)到更好的效果。
不同的比賽可能會有不同的限制和要求,參賽者也應(yīng)該熟悉比賽規(guī)則和評測系統(tǒng),針對性地選擇和實(shí)現(xiàn)算法。
計(jì)算機(jī)系學(xué)生為什么要刷算法——— by 柳婼
很多?(尤其是?些初??開發(fā)的計(jì)算機(jī)學(xué)?)可能會覺得算法在開發(fā)過程中的?處不?,甚?很多沒有認(rèn)真學(xué)過算法的?程序員都會這樣認(rèn)為,然?并不是這樣~
?先,刷算法可以培養(yǎng)清晰的邏輯思維能?,改變?的思維?式,使?對待復(fù)雜的代碼問題更容易看透本質(zhì)~在未來做?程項(xiàng)?的過程中也會慢慢發(fā)現(xiàn),當(dāng)年認(rèn)真學(xué)過的算法也并?當(dāng)初想得那樣毫??處,反?能提?解決問題的效率,使??能?更簡單的?法、更精簡的代碼解決實(shí)際問題~
其次,看過很多IT公司招聘信息的?就會發(fā)現(xiàn),他們都會優(yōu)先選擇有?定算法基礎(chǔ)的?,尤其是?些?公司在?試過程中,對于應(yīng)屆?,更多考察的是數(shù)據(jù)結(jié)構(gòu)與算法、計(jì)算機(jī)?絡(luò)、操作系統(tǒng)等這些計(jì)算機(jī)基礎(chǔ)課程,?并?都是在考察實(shí)際應(yīng)聘崗位的相關(guān)技術(shù)、?具、知識等~
再者,提?算法能?不是?蹴?就的,需要靜下?來???的時間去看書、學(xué)習(xí)、刷題、找bug或者參加競賽,也許市?上有很多開發(fā)類的培訓(xùn)班,如前端、JavaWeb、安卓之類,但鮮有算法類的培訓(xùn),因?yàn)閷W(xué)習(xí)算法是實(shí)實(shí)在在、需要??付出努?的過程,??對題?的思考、學(xué)習(xí)、鉆研,別??法替代,也不可能通過培訓(xùn)速成。所以這也是為什么很多公司會在應(yīng)聘的筆試?試環(huán)節(jié)考察算法能?的原因,也許語?的特性、?具的使?、開發(fā)的技巧可以短期培訓(xùn),但數(shù)據(jù)結(jié)構(gòu)和算法的能??以證明應(yīng)聘者在計(jì)算機(jī)知識??的硬實(shí)?~?且很多?公司在考察算法時都是?板編程,這?寫代碼更能考驗(yàn)應(yīng)試者的?平~
最后,如果從短期?度來說,可能刷算法能帶來的?些看得?的收益會給??更多的動?,?如:PAT?級刷完可以讓??在C語??級或者C語?期末考試中獲得?個?分;PAT甲級能讓??在考浙?時候直接抵復(fù)試中機(jī)試的成績;PAT甲級考?分能讓??收到?些?公司的?試邀請;LeetCode能夠讓??在?試很多?公司尤其是國外?些公司(Google、微軟、Facebook、Amazon等)時正確解答出筆試和?試的算法問題等…?論是?期還是短期來看,刷算法對于有追求的計(jì)算機(jī)學(xué)?都是必經(jīng)之路~
什么是OJ,以及對AC、WA、TLE、CE、RE、MLE、PE等狀態(tài)術(shù)語的解釋
OJ(Online Judge)是指在線判題系統(tǒng),將代碼提交給OJ后,OJ會在線檢測程序源代碼的正確性,并返回結(jié)果~
國內(nèi)著名的OJ系統(tǒng)有POJ(北京?學(xué)OJ)、杭電OJ(參加過ACM的?都知道)等,PAT的官?題庫、藍(lán)橋杯題庫和LeetCode也是OJ系統(tǒng),都可以在線提交代碼并得到返回結(jié)果~
PAT考試過程中使?的就是和平時刷題題庫?樣的OJ判題系統(tǒng),?藍(lán)橋杯在考試的時候只能提交答案,不能實(shí)時看到提交的答案是否正確,但藍(lán)橋杯平時刷題練習(xí)的題庫是OJ~
相???,PAT和藍(lán)橋需要的都是完整的有輸?輸出的代碼段,?LeetCode并不需要輸?輸出,?是將需要填寫的代碼包在?個Solution類?,甚?會給好Solution類中的函數(shù),涉及到樹的題?還會給出樹的定義,我們只需要在這個函數(shù)中填充代碼并按照題?的要求返回相應(yīng)類型的值即可~
刷算法OJ過程中提交答案后會返回的?些狀態(tài)術(shù)語,
AC (Accepted = 答案正確),WA (WrongAnswer = 答案錯誤), TLE (Time Limit Exceeded = 運(yùn)?超時 / 時間超限), CE (Compile Error =編譯錯誤), RE (Runtime Error = 運(yùn)?時出錯), MLE (Memory Limit Exceeded = 內(nèi)存超限), PE (Presentation Error = 格式錯誤)
如果刷過leetcode的?對這些應(yīng)該?熟悉~所以我們經(jīng)常會說 AC 了幾道題、 TLE 了或者 WA 了之類的~?PAT的OJ?返回的是中?反饋信息,例如答案正確、格式錯誤、內(nèi)存超限、運(yùn)?超時、段錯誤等~
相關(guān)鏈接:
算法競賽從了解入坑到快速放棄指南
https://www.zhihu.com/tardis/zm/art/29598587?source_id=1005
算法競賽并不是適合所有的人,需要堅(jiān)持,堅(jiān)持,再堅(jiān)持,半途而廢的人很多很多;入門不需要太深的數(shù)學(xué)能力,畢竟我們是工科生,并非理科生;入門的話,數(shù)理化沒什么大礙;但是,想要一直深入走下去,走向ICPC——數(shù)學(xué)能力十分重要、數(shù)學(xué)專業(yè)的學(xué)生優(yōu)勢更大;走著走著,你會發(fā)現(xiàn)你的對手可能就是雙一流大學(xué)的、信息學(xué)競賽保送的、花式保送的、從小學(xué)開始學(xué)起計(jì)算機(jī)語言的(直接起點(diǎn)比你早五六年)等等。
零基礎(chǔ)的大一新生如何學(xué)好算法
如果你是一個零基礎(chǔ)的大一新生,想要學(xué)好算法,以下是一些建議:
-
建立計(jì)算機(jī)基礎(chǔ)知識:首先,確保你對計(jì)算機(jī)科學(xué)基礎(chǔ)有一定的了解。學(xué)習(xí)計(jì)算機(jī)組成原理、數(shù)據(jù)結(jié)構(gòu)和算法分析等基礎(chǔ)概念。可以通過閱讀相關(guān)教材、觀看在線教育平臺的視頻課程或參加大學(xué)的計(jì)算機(jī)基礎(chǔ)課程來學(xué)習(xí)。
-
學(xué)習(xí)編程語言:選擇一門常用的編程語言作為學(xué)習(xí)工具,如Python或Java。這些語言相對易于學(xué)習(xí),擁有豐富的資源和社區(qū)支持。通過學(xué)習(xí)編程語言,你將能夠理解和實(shí)現(xiàn)算法。
-
掌握基本的數(shù)據(jù)結(jié)構(gòu):數(shù)據(jù)結(jié)構(gòu)是算法的基礎(chǔ)。學(xué)習(xí)各種常見的數(shù)據(jù)結(jié)構(gòu),如數(shù)組、鏈表、棧、隊(duì)列、樹和圖等。理解它們的特點(diǎn)、操作和應(yīng)用場景??梢允褂媒滩?、在線教程和練習(xí)題來鞏固學(xué)習(xí)。
-
學(xué)習(xí)基本的算法概念:了解各種基本算法的概念和原理,如排序、查找、遞歸、動態(tài)規(guī)劃和貪心算法等。通過閱讀教材、觀看在線視頻和參考實(shí)例代碼來學(xué)習(xí)算法。
-
刷題練習(xí):通過刷題來提高算法能力。開始從簡單的題目開始,逐漸增加難度。可以使用在線編程平臺(如LeetCode、HackerRank等)提供的算法題庫來進(jìn)行練習(xí)。
-
尋找合適的學(xué)習(xí)資源:在學(xué)習(xí)過程中,尋找一些優(yōu)質(zhì)的學(xué)習(xí)資源,如經(jīng)典的算法教材、在線教程、博客和視頻教程等。這些資源將為你提供更多的學(xué)習(xí)內(nèi)容和實(shí)踐經(jīng)驗(yàn)。
-
多與他人交流與合作:參加學(xué)習(xí)小組、參與在線算法社區(qū)或與同學(xué)進(jìn)行討論與交流。與他人分享知識和經(jīng)驗(yàn),共同解決問題,能夠加深理解并拓寬思路。
-
注重實(shí)踐和項(xiàng)目經(jīng)驗(yàn):將所學(xué)的算法知識應(yīng)用于實(shí)際項(xiàng)目中。嘗試解決一些實(shí)際問題,或者參與一些開源項(xiàng)目。通過實(shí)際操作,加強(qiáng)對算法的理解和應(yīng)用能力。
記住,學(xué)習(xí)算法需要時間和堅(jiān)持。不要急于求成,要保持積極的學(xué)習(xí)態(tài)度,并通過不斷地實(shí)踐和挑戰(zhàn)來提高自己的算法水平。
C語言入門強(qiáng)烈推薦浙江大學(xué)翁愷老師的課程
關(guān)于ICPC
ICPC的全程為International Collegiate Programming Contest,是世界上歷史最悠久、規(guī)模最大、最負(fù)盛名的編程競賽。因?yàn)樵?977-2017期間該賽事由ACM(計(jì)算機(jī)協(xié)會)主持,所以也有人叫它ACM-ICPC。ICPC比賽主要面
向大一到研一的同學(xué)。
在中國還有一項(xiàng)賽事為CCPC(中國大學(xué)生程序設(shè)計(jì)競賽),主要面向國內(nèi)高校,賽制與難度與ICPC持平,習(xí)慣上我們把ICPC與CCPC統(tǒng)稱為XCPC。
如果要參加XCPC相關(guān)比賽,通常來講需要先選拔進(jìn)入校隊(duì),然后三人組隊(duì)。每年每個人只能參加兩次ICPC區(qū)域賽,根據(jù)比賽結(jié)果會角逐出進(jìn)入EC final甚至World final的隊(duì)伍。
XCPC相關(guān)比賽是一場關(guān)于智力與汗水的比拼,有著極高的難度上限,參賽者能享受到算法競賽實(shí)時競技無與倫比的樂趣。如果你也愛好解決難題,挑戰(zhàn)自己的極限,請一定不要錯過。
推薦給萌新的訓(xùn)練方法
剛剛?cè)肟?/h4>
學(xué)習(xí)算法競賽其實(shí)不用太依賴于紙質(zhì)資料,參考網(wǎng)上的資源已足夠,XCPC涉及的算法可參見OI-wiki如果剛剛接觸算法競賽,請不要過分執(zhí)著于學(xué)習(xí)過于復(fù)雜的算法,而是要著眼于提升分析問題,解決實(shí)際題目的基本能力。這里推薦大家參加Codeforces的div1-div4系列比賽(Codeforces游玩攻略)
但是Codeforces(以下簡稱為cf)的比賽多在晚上10點(diǎn)35分舉行,如果時間安排不過來的,可以下來自己做題,也可使用virtual contest定時訓(xùn)練。
在這個階段里,建議大家在做題過程中學(xué)習(xí)未掌握的算法。切記要多多閱讀題解給出的標(biāo)程,并學(xué)習(xí)標(biāo)程的代碼寫法,這樣大有裨益。在做題時,推薦大家要想清楚思路后再寫,時刻牢記,Think twice,Code once
入門之后
當(dāng)cf的rating來到1700之后,大家可以逐漸學(xué)習(xí)一些較復(fù)雜的算法,可以結(jié)合OI-wiki。其實(shí)cf的比賽題目碼量和涉及到的算法復(fù)雜程度還是遜于常規(guī)ICPC區(qū)域賽的,所以大家還要多去cf的Gym中做做真題。
這里推薦一下筆者使用Virtual Judge的方法。
假如想要提升cf的rating,可以自己在Virtual Judge上拉一場比賽,主要選擇在自己水平線或者之上的題目。例如,你的cf rating為1900,則可以拉3道div2D,3道div2E的題目,組成一場時長三小時的比賽,然后訓(xùn)練結(jié)束后再補(bǔ)完所有題目。訓(xùn)練完一場區(qū)域賽后,總會有題目沒有做出來或者甚至沒時間看。對于那些通過人數(shù)較少的題目,建議結(jié)合自身情況補(bǔ)題,希望大家有敢于與題目死磕的精神,其實(shí)一道題做一兩天是很正常的當(dāng)然,如果過于困難了還是要懂得放棄,君子報(bào)仇十年不晚。如果有些題目訓(xùn)練時沒有看,但是通過的人數(shù)較多,是自己有可能獨(dú)立做出的,可以記錄下來,累計(jì)到3-4題后,可以用這些題目去Virtual Judge上拉一場二-三小時的比賽。
寫在后
ICPC需要長期的付出與訓(xùn)練,并不是一個投資少見效快的“高性價比”比賽。但是這項(xiàng)賽事對于能力的提升是巨大的,特別是那些想要本科畢業(yè)就進(jìn)入大廠就業(yè)的同學(xué)來說,ICPC的參賽經(jīng)歷是一塊寶貴的敲門磚。但是不論你是為了畢業(yè)后更好的就業(yè),還是說單純喜歡學(xué)習(xí)算法與數(shù)學(xué),你一定都能在比賽中收獲良多。
計(jì)協(xié)大三學(xué)長建議:
省賽
如果你是從未接觸過算法競賽的小白,那你首先要考慮的內(nèi)容是如何面對省賽,畢竟拿到省一等獎才有資格去參加國賽嘛,那你所需要準(zhǔn)備的內(nèi)容以及難度不算太難.
語法 思維(cf 800)
一.算法(序號表示優(yōu)先級)
1.枚舉
掌握枚舉思想,就是寫暴力,省賽會寫暴力加一點(diǎn)點(diǎn)算法就能出線了,這里的枚舉主要包括,循環(huán)遍歷、DFS
Oi 藍(lán)橋杯
Acm icpc 各種周賽
ioi 天梯賽 cccc gplt
2.排序
一般配合著枚舉使用,一般來說會sort就好了,當(dāng)然作為學(xué)習(xí)來說手寫一下冒泡、選擇、歸并、快排、堆排 等都是可以的。(掌握sort、 priority_queue(堆))
Stl(c++)
3.雙指針、前綴和、二分、差分、遞推
常用得基本算法思想用來優(yōu)化算法復(fù)雜度的入門算法(大量刷題、這是基本分)
4.最大公約數(shù)、最小公倍數(shù)、素?cái)?shù)
掌握其中關(guān)系、素?cái)?shù)篩(歐拉篩、埃氏篩)
5.動態(tài)規(guī)劃(學(xué)到這就有機(jī)會省一了)
6.圖論、字符串算法
最短路徑(Dijktra、spfa、Floyd)、最小生成樹(prim、Kruskal)、BFS、DFS、KMP、字典樹
二.基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)(無先后順序)
其實(shí)在第一部分的內(nèi)容里就會學(xué)到相關(guān)的內(nèi)容了,主要配合著算法使用、作為一種思想
1.棧
單調(diào)棧
2.隊(duì)列(BFS)
單調(diào)隊(duì)列
3.堆(堆排序 priority_queue)
4.鏈表(鄰接表的思想)
5.哈希表
6.并查集(Kruskal)
其實(shí)數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)在各種語言中都有封裝好現(xiàn)成的可以使用(C++STL是必須要會用的)
具體訓(xùn)練:
首先是根據(jù)要學(xué)的內(nèi)容去刷題,一題一題刷,這里首推洛谷題單,整理的很好,只要跟著寫就好了.建議把入門也刷了,可以練一下基本功,否則要是被一些奇怪的輸出輸入卡了就不好了.其次可以去牛客,有條件的買課只推Acwing跟著練就完了.
在算法競賽中,一定要記住,思維能力和直覺是核心驅(qū)動力,在思維能力達(dá)到一定層次以后,算法的學(xué)習(xí)能力也自然而然上來。
1、快速將語法過關(guān),學(xué)習(xí)基礎(chǔ)算法,如單調(diào)棧,動態(tài)規(guī)劃,dfs,Ica, 二分,基礎(chǔ)圖論,整除,取余,尺取,貪心等,可以上洛谷官方題單板刷,然后去刷hdu入門題,也可以去acwing刷刷基礎(chǔ)
2、打開codeforces, 千萬不要沒聽過就害怕!只要嘗試去做幾道題,就會不斷收益良多! ! !在problemset里選1000到1600級別題中找到適合自己難度的題,可以二分查找(check是30分鐘內(nèi)能否獨(dú)立查出), 最好選擇contrustive(構(gòu)造) 對思維提高最大,然后看看能不能30分鐘獨(dú)立推理出來,一定要獨(dú)立思考,不要覺得怎么也想不到就覺得受挫,也不要立刻看題解!在怎么也想不到的情況下尋找一條路是鍛煉直覺的關(guān)鍵,這種想不到卻依舊得去想的經(jīng)歷也是直覺提高的重要鋪墊! (除非你是天才),不斷去做,如果連續(xù)幾次在30分鐘內(nèi)想出這個級別題,就去做這個級別題+100難度的題,然后堅(jiān)持想30分鐘,在想的過程中不斷尋找可能的方向,想不出來看題解,有不知道的小技巧,小坑點(diǎn)都要記下來,有不懂的算法或特殊應(yīng)用可以學(xué)會,用這種方法不斷把上限提高
(重點(diǎn))3、經(jīng)常打acwing,牛客,和cf的比賽,不斷驗(yàn)證自己的實(shí)力,而且打線上比賽很重要的是能提高競賽能力,同時把比賽中會踩的坑都踩了,在一定的場次之后就可以只作為驗(yàn)證實(shí)力提高的標(biāo)準(zhǔn)了
刷題過程中如何平衡??寫代碼和看他?代碼的?糾結(jié)——— by 柳婼
可能很多?在刷算法過程中,會覺得??寫不出來的時候看了別?寫的代碼就不是??的了,感覺像是抄了?遍別?的代碼,覺得不是??想出來的印象不夠深刻,可能因?yàn)?時候做數(shù)學(xué)題的時候,發(fā)現(xiàn)?師講了?遍的數(shù)學(xué)題??沒記住,但是??獨(dú)?思考然后做出來的卻印象很深刻…所以覺得寫代碼的過程中也應(yīng)該盡量保持獨(dú)??主完成~其實(shí)我覺得這樣的想法是不太對的哦~
算法這個神奇的東東,有它?身的?些特點(diǎn),?如?道PAT題?,可能你看了題?后覺得??有?點(diǎn)思路了,畢竟只是給個輸?要求你給出正確的輸出嘛,或多或少還是有些??的想法的,就開始??寫,結(jié)果沒能AC,修修補(bǔ)補(bǔ)改改也勉強(qiáng)最后AC了,但是代碼卻冗?繁瑣,過陣?讓你再做?遍這道題?沒有思路了…
算法題就是這樣,總給你?種好像也不是太難的感覺,?且這種提交后會看到??得分的真題題庫總會讓?產(chǎn)??種當(dāng)作?次正式考試測試?下??的?平的想法,導(dǎo)致很多?刷算法完完全全就是在把??僅有的思維和編程語法知識完全倒出來展現(xiàn)在代碼?,如果這個?是個競賽??倒也沒什么關(guān)系,但是如果基礎(chǔ)不太好,直接??寫?排斥看他?代碼的想法是對??的算法提升是?常不利的,可能你冗??思路不夠清晰的代碼確實(shí)AC了這道題,但是你可能也錯過了向更優(yōu)秀思路的代碼學(xué)習(xí)的機(jī)會。
反?那些沒什么思路的?,可能去看了別?優(yōu)秀的代碼,讓??學(xué)會遇到這類算法題的清晰思路,還學(xué)了?些下次能?得到的編程語?技巧(?如18年12?PAT考試結(jié)束后,?位可愛的?學(xué)弟來感謝我學(xué)了我代碼中的s.substr()的?法,讓他考試的時候直接AC了?道題,增強(qiáng)了考試時的信?,考試的后半段時間做題狀態(tài)很好多拿了很多分)所以我建議不管這道題你寫出來的代碼是AC了還是做錯了找不到bug,都應(yīng)該看?看別?解這道題的代碼是不是和你思路相同~
在我刷題的時候,如果??的代碼和別?思路?法完全不同,那我會思考,我所寫的?法是不是?別?寫的代碼優(yōu)秀?很多時候會發(fā)現(xiàn),并不能找到錯誤原因的那段代碼本身邏輯就為混亂,所以我的建議是直接刪掉原來寫的,對??寫的代碼?更好的?法進(jìn)?重構(gòu),因?yàn)榧词惯@段代碼勉強(qiáng)調(diào)試寫出來了,下?次?到它還是難以理解,對??的考前復(fù)習(xí)也是?種打擊,會讓??看到這段代碼就想要跳過不看,?且還讓??錯過了?次學(xué)習(xí)他?優(yōu)秀?法的機(jī)會,要知道刷題的真正意義是學(xué)到知識呀~
經(jīng)典題目分析leetcode第一題
(有人相愛,有人夜里開車看海,有人leetcode第一題都做不出來??)
題目
給定一個整數(shù)數(shù)組 nums 和一個整數(shù)目標(biāo)值 target,請你在該數(shù)組中找出 和為目標(biāo)值 target 的那 兩個 整數(shù),并返回它們的數(shù)組下標(biāo)。
你可以假設(shè)每種輸入只會對應(yīng)一個答案。但是,數(shù)組中同一個元素在答案里不能重復(fù)出現(xiàn)。
你可以按任意順序返回答案。
示例 1:
輸入:nums = [2,7,11,15], target = 9
輸出:[0,1]
解釋:因?yàn)?nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
輸入:nums = [3,2,4], target = 6
輸出:[1,2]
示例 3:
輸入:nums = [3,3], target = 6
輸出:[0,1]
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只會存在一個有效答案
進(jìn)階:你可以想出一個時間復(fù)雜度小于 O(n2) 的算法嗎?
分析
方法一:暴力枚舉
思路及算法
最容易想到的方法是枚舉數(shù)組中的每一個數(shù) x,尋找數(shù)組中是否存在 target - x。
當(dāng)我們使用遍歷整個數(shù)組的方式尋找 target - x 時,需要注意到每一個位于 x 之前的元素都已經(jīng)和 x 匹配過,因此不需要再進(jìn)行匹配。而每一個元素不能被使用兩次,所以我們只需要在 x 后面的元素中尋找 target - x。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int n = nums.size();
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (nums[i] + nums[j] == target) {
return {i, j};
}
}
}
return {};
}
};
來源:力扣(LeetCode)
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
上述代碼是一個簡單的解決LeetCode上"兩數(shù)之和"問題的實(shí)現(xiàn)。下面對該代碼的復(fù)雜度進(jìn)行分析。
設(shè)輸入的數(shù)組長度為n。
- 外層循環(huán):i從0到n-1,共進(jìn)行n次迭代。
- 內(nèi)層循環(huán):j從i+1到n-1,平均情況下進(jìn)行(n-1-i)/2次迭代(假設(shè)n足夠大)。
因此,總的迭代次數(shù)為:
n + (n-1) + (n-2) + … + 1 ≈ n^2 / 2
由于內(nèi)層循環(huán)中只有常數(shù)次的操作,可以忽略不計(jì),所以算法的時間復(fù)雜度為O(n^2)。
在空間復(fù)雜度方面,除了存儲結(jié)果的返回?cái)?shù)組外,算法并沒有使用額外的空間,因此空間復(fù)雜度為O(1)(常數(shù)級別)。
需要注意的是,由于解決兩數(shù)之和問題的最優(yōu)解是哈希表,其時間復(fù)雜度為O(n),因此上述代碼存在較高的時間復(fù)雜度,不是最優(yōu)解。但在一些規(guī)模較小的問題上,該算法的實(shí)際性能可能仍然可接受。
作者:LeetCode-Solution
鏈接:https://leetcode.cn/problems/two-sum/solution/liang-shu-zhi-he-by-leetcode-solution/
來源:力扣(LeetCode)
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
方法二:哈希表
哈希表(Hash Table),也被稱為散列表,是一種常用的數(shù)據(jù)結(jié)構(gòu)。它通過利用哈希函數(shù)(Hash Function)來實(shí)現(xiàn)快速的數(shù)據(jù)插入、刪除和查找操作。
哈希表由一個數(shù)組和哈希函數(shù)組成。哈希函數(shù)將每個元素映射到數(shù)組中的一個位置,該位置稱為哈希值或哈希碼。數(shù)組的索引即為哈希值,可以直接訪問到對應(yīng)位置的元素。
具體的工作原理如下:
- 對于要插入或查找的元素,首先經(jīng)過哈希函數(shù)得到它的哈希值。
- 將元素存儲在計(jì)算得到的哈希值對應(yīng)的數(shù)組位置上。
- 若存在相同的哈希值,則可能發(fā)生沖突(Hash Collision)。沖突可以通過使用開放尋址法和鏈地址法來解決。
- 開放尋址法:當(dāng)發(fā)生沖突時,不斷地探測下一個空閑位置,直到找到合適的位置插入元素。
- 鏈地址法:在哈希表的每個位置上維護(hù)一個鏈表,每個鏈表存儲哈希值相同的元素,沖突時將元素插入鏈表中。
- 插入和查找元素時,再次通過哈希函數(shù)計(jì)算哈希值,然后在對應(yīng)位置上進(jìn)行操作。
哈希表通過利用哈希函數(shù)的快速計(jì)算和數(shù)組的隨機(jī)訪問特性,實(shí)現(xiàn)了高效的元素插入、刪除和查找。在理想情況下,哈希表的插入、刪除和查找操作的平均時間復(fù)雜度為O(1)。
哈希表在很多應(yīng)用中都得到廣泛的使用,例如數(shù)據(jù)庫索引、緩存系統(tǒng)、編譯器中的符號表等。
思路及算法
注意到方法一的時間復(fù)雜度較高的原因是尋找 target - x 的時間復(fù)雜度過高。因此,我們需要一種更優(yōu)秀的方法,能夠快速尋找數(shù)組中是否存在目標(biāo)元素。如果存在,我們需要找出它的索引。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hashtable;
for (int i = 0; i < nums.size(); ++i) {
auto it = hashtable.find(target - nums[i]);
if (it != hashtable.end()) {
return {it->second, i};
}
hashtable[nums[i]] = i;
}
return {};
}
};
上述代碼是使用哈希表來解決LeetCode上"兩數(shù)之和"問題的實(shí)現(xiàn)。該算法的時間復(fù)雜度為O(n),空間復(fù)雜度為O(n)。
具體分析如下:
- 創(chuàng)建一個哈希表 hashtable,用于存儲數(shù)組中的元素及其對應(yīng)的索引。
- 遍歷數(shù)組 nums,對于每個元素 nums[i],進(jìn)行以下操作:
- 在哈希表 hashtable 中尋找是否存在 target - nums[i] 的鍵值對,即找到了另外一個數(shù)與當(dāng)前數(shù)之和為目標(biāo)值 target。
- 如果找到了,返回對應(yīng)的索引和當(dāng)前元素的索引。
- 如果沒有找到,將當(dāng)前元素 nums[i] 插入哈希表 hashtable 中,鍵為元素值,值為元素索引。
- 如果遍歷結(jié)束仍未找到滿足條件的元素對,返回空數(shù)組。
在這個算法中,通過哈希表的快速查找特性,將尋找 target - x 的時間復(fù)雜度降低為O(1)。因此,總的時間復(fù)雜度為O(n)。同時,哈希表用來存儲元素及其索引,所需的額外空間為O(n)。
相比于方法一,方法二使用哈希表使得算法的時間復(fù)雜度大幅降低,是更優(yōu)的解法。
進(jìn)階:你可以想出一個時間復(fù)雜度小于 O(n2) 的算法嗎?
當(dāng)然可以!通過使用兩個指針,可以將時間復(fù)雜度降低到O(n)。下面是一個優(yōu)化的算法:
假設(shè)有一個排序好的數(shù)組,并且我們要找到兩個數(shù)之和等于目標(biāo)值target。使用雙指針方法可以高效地解決這個問題。
- 初始化兩個指針left和right,分別指向數(shù)組的開頭和結(jié)尾。
- 計(jì)算兩個指針指向的元素的和sum。
- 如果sum等于target,那么找到了兩個數(shù)的和等于目標(biāo)值,返回它們的索引。
- 如果sum小于target,說明需要增加兩個數(shù)的和,因此將left指針右移一位。
- 如果sum大于target,說明需要減小兩個數(shù)的和,因此將right指針左移一位。
- 重復(fù)步驟2直到找到滿足條件的兩個數(shù),或者left大于等于right時停止搜索。
這個算法的時間復(fù)雜度為O(n),因?yàn)樵谧顗那闆r下,我們需要遍歷數(shù)組一次。而空間復(fù)雜度仍為O(1),因?yàn)橹恍枰~外存儲兩個指針的索引。
需要注意的是,這個方法適用于已經(jīng)排序好的數(shù)組。如果輸入的數(shù)組無序,我們可以先對其進(jìn)行排序,然后再使用雙指針方法。
def two_sum(nums, target):
left = 0
right = len(nums) - 1
while left < right:
sum = nums[left] + nums[right]
if sum == target:
return [left, right]
elif sum < target:
left += 1
else:
right -= 1
# 若找不到滿足條件的兩個數(shù),則返回空列表
return []
# 示例輸入
nums = [-2, 0, 3, 6, 7, 9, 11]
target = 9
result = two_sum(nums, target)
if result:
print("找到滿足條件的兩個數(shù)的索引:", result)
else:
print("找不到滿足條件的兩個數(shù)")
代碼隨想錄:
https://www.bilibili.com/video/BV1aT41177mK/
思路
很明顯暴力的解法是兩層for循環(huán)查找,時間復(fù)雜度是O(n^2)。
本題呢,則要使用map,那么來看一下使用數(shù)組和set來做哈希法的局限。
數(shù)組的大小是受限制的,而且如果元素很少,而哈希值太大會造成內(nèi)存空間的浪費(fèi)。
set是一個集合,里面放的元素只能是一個key,而兩數(shù)之和這道題目,不僅要判斷y是否存在而且還要記錄y的下表位置,因?yàn)橐祷豿 和 y的下表。所以set 也不能用。
此時就要選擇另一種數(shù)據(jù)結(jié)構(gòu):map ,map是一種key value的存儲結(jié)構(gòu),可以用key保存數(shù)值,用value在保存數(shù)值所在的下表。
C++中map,有三種類型: 如圖
std::unordered_map 底層實(shí)現(xiàn)為哈希表,std::map 和std::multimap 的底層實(shí)現(xiàn)是紅黑樹。
同理,std::map 和std::multimap 的key也是有序的(這個問題也經(jīng)常作為面試題,考察對語言容器底層的理解)。 更多哈希表的理論知識請看關(guān)于哈希表,你該了解這些!。
這道題目中并不需要key有序,選擇std::unordered_map 效率更高!使用其他語言的錄友注意了解一下自己所用語言的map結(jié)構(gòu)的內(nèi)容實(shí)現(xiàn)原理。
接下來需要明確兩點(diǎn):
map用來做什么
map中key和value分別表示什么
map目的用來存放我們訪問過的元素,因?yàn)楸闅v數(shù)組的時候,需要記錄我們之前遍歷過哪些元素和對應(yīng)的下表,這樣才能找到與當(dāng)前元素相匹配的(也就是相加等于target)
接下來是map中key和value分別表示什么。
這道題 我們需要 給出一個元素,判斷這個元素是否出現(xiàn)過,如果出現(xiàn)過,返回這個元素的下標(biāo)。
那么判斷元素是否出現(xiàn),這個元素就要作為key,所以數(shù)組中的元素作為key,有key對應(yīng)的就是value,value用來存下標(biāo)。
所以 map中的存儲結(jié)構(gòu)為 {key:數(shù)據(jù)元素,value:數(shù)組元素對應(yīng)的下表}。
在遍歷數(shù)組的時候,只需要向map去查詢是否有和目前遍歷元素比配的數(shù)值,如果有,就找到的匹配對,如果沒有,就把目前遍歷的元素放進(jìn)map中,因?yàn)閙ap存放的就是我們訪問過的元素。
過程如下:
!過程一
!過程二
C++代碼:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
std::unordered_map <int,int> map;
for(int i = 0; i < nums.size(); i++) {
// 遍歷當(dāng)前元素,并在map中尋找是否有匹配的key
auto iter = map.find(target - nums[i]);
if(iter != map.end()) {
return {iter->second, i};
}
// 如果沒找到匹配對,就把訪問過的元素和下標(biāo)加入到map中
map.insert(pair<int, int>(nums[i], i));
}
return {};
}
};
總結(jié)
這道題目關(guān)鍵是在于明確map是用來做什么的,map中的key和value用來存什么的。
這個想清楚了,題目代碼就比較清晰了。
很多錄友把這道題目 通過了,但都沒想清楚map是用來做什么的,以至于對代碼的理解其實(shí)是 一知半解的。
其他語言版本
Java:
public int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
if(nums == null || nums.length == 0){
return res;
}
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
int temp = target - nums[i];
if(map.containsKey(temp)){
res[1] = i;
res[0] = map.get(temp);
}
map.put(nums[i], i);
}
return res;
}
Python:
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
records = dict()
# 用枚舉更方便,就不需要通過索引再去取當(dāng)前位置的值
for idx, val in enumerate(nums):
if target - val not in records:
records[val] = idx
else:
return [records[target - val], idx] # 如果存在就返回字典記錄索引和當(dāng)前索引
Go:
func twoSum(nums []int, target int) []int {
for k1, _ := range nums {
for k2 := k1 + 1; k2 < len(nums); k2++ {
if target == nums[k1] + nums[k2] {
return []int{k1, k2}
}
}
}
return []int{}
}
// 使用map方式解題,降低時間復(fù)雜度
func twoSum(nums []int, target int) []int {
m := make(map[int]int)
for index, val := range nums {
if preIndex, ok := m[target-val]; ok {
return []int{preIndex, index}
} else {
m[val] = index
}
}
return []int{}
}
Rust
use std::collections::HashMap;
impl Solution {
pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
let mut map = HashMap::with_capacity(nums.len());
for i in 0..nums.len() {
if let Some(k) = map.get(&(target - nums[i])) {
if *k != i {
return vec![*k as i32, i as i32];
}
}
map.insert(nums[i], i);
}
panic!("not found")
}
}
Javascript
var twoSum = function (nums, target) {
let hash = {};
for (let i = 0; i < nums.length; i++) {
if (hash[target - nums[i]] !== undefined) {
return [i, hash[target - nums[i]]];
}
hash[nums[i]] = i;
}
return [];
};
php
function twoSum(array $nums, int $target): array
{
for ($i = 0; $i < count($nums);$i++) {
// 計(jì)算剩下的數(shù)
$residue = $target - $nums[$i];
// 匹配的index,有則返回index, 無則返回false
$match_index = array_search($residue, $nums);
if ($match_index !== false && $match_index != $i) {
return array($i, $match_index);
}
}
return [];
}
Swift:
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
var res = [Int]()
var dict = [Int : Int]()
for i in 0 ..< nums.count {
let other = target - nums[i]
if dict.keys.contains(other) {
res.append(i)
res.append(dict[other]!)
return res
}
dict[nums[i]] = i
}
return res
}
Scala:
object Solution {
// 導(dǎo)入包
import scala.collection.mutable
def twoSum(nums: Array[Int], target: Int): Array[Int] = {
// key存儲值,value存儲下標(biāo)
val map = new mutable.HashMap[Int, Int]()
for (i <- nums.indices) {
val tmp = target - nums(i) // 計(jì)算差值
// 如果這個差值存在于map,則說明找到了結(jié)果
if (map.contains(tmp)) {
return Array(map.get(tmp).get, i)
}
// 如果不包含把當(dāng)前值與其下標(biāo)放到map
map.put(nums(i), i)
}
// 如果沒有找到直接返回一個空的數(shù)組,return關(guān)鍵字可以省略
new Array[Int](2)
}
}
C#:
public class Solution {
public int[] TwoSum(int[] nums, int target) {
Dictionary<int ,int> dic= new Dictionary<int,int>();
for(int i=0;i<nums.Length;i++){
int imp= target-nums[i];
if(dic.ContainsKey(imp)&&dic[imp]!=i){
return new int[]{i, dic[imp]};
}
if(!dic.ContainsKey(nums[i])){
dic.Add(nums[i],i);
}
}
return new int[]{0, 0};
}
}
圖解算法:
比賽舉例
https://zhuanlan.zhihu.com/p/120404245
藍(lán)橋杯(官網(wǎng):http://dasai.lanqiao.cn/pages/dasai/index.html)
報(bào)名時間:一般為每年9月份-12月份。
舉辦時間:一般是報(bào)名次年的3月份省賽、6月份決賽(2020年因疫情推遲),拿到省賽一等獎才能進(jìn)入在北京舉行的全國總決賽。每年舉辦一次,2020年為第11屆。
報(bào)名費(fèi):300元。
可選語言:c/c++,java,python。
參賽要求:具有正式全日制學(xué)籍并且符合相關(guān)科目報(bào)名要求的研究生、本科及高職高專學(xué)生(以報(bào)名時狀態(tài)為準(zhǔn)),以個人為單位進(jìn)行比賽。
分組說明:研究生組、大學(xué)A組、大學(xué)B組、大學(xué)C組。研究生只能報(bào)研究生組。985、211本科生只能報(bào)大學(xué)A組及以上組別,其它院校本科生可自行選擇報(bào)大學(xué)B組及以上組別,高職高專院??蓤?bào)大學(xué)C組或自行選擇任意組別。python方向僅設(shè)置大學(xué)組。各組的題目只有部分相同,各組分開比賽、分開評獎。
比賽時長:4小時。
比賽地點(diǎn):線下比賽。省賽在全國各地都有賽點(diǎn),決賽統(tǒng)一在北京舉行。
比賽題型:5道填空題+5道編程題,填空題一般也是需要編程來求解的,滿分150分。
比賽賽制:OI賽制,即每道題提交之后都沒有任何反饋,填空題不是滿分就是0分,編程題最后根據(jù)每道題通過的測試點(diǎn)的數(shù)量獲得相應(yīng)的分?jǐn)?shù)。每道題不限制提交次數(shù),僅以最后一次提交為準(zhǔn)。
往年真題:http://dasai.lanqiao.cn/pages/dasai/news_detail_w.html?id=644
官方練習(xí)系統(tǒng):http://lx.lanqiao.cn/
獲獎:比賽分為省賽和決賽,所有獲獎選手均可獲得由工業(yè)和信息化部人才交流中心及大賽組委會聯(lián)合頒發(fā)的獲獎證書。
省賽:省賽每個組別設(shè)置一、二、三等獎,比例分別為10%、20%、30%。省賽一等獎選手可獲得進(jìn)入在北京舉行的全國總決賽的資格。
決賽:決賽一等獎5%,二等獎20%,三等獎25%,優(yōu)秀獎不超過50%,零分卷不得獎。
PAT(計(jì)算機(jī)程序設(shè)計(jì)能力考試,官網(wǎng):https://www.patest.cn/)
舉辦時間:每年舉辦3次,一般為每年3月(2020年因疫情推遲到6月21日)、9月和12月。
報(bào)名時間:一般上次考試剛剛結(jié)束,下次考試的報(bào)名就馬上開始了。
報(bào)名費(fèi):256元。只需要刷十道??途W(wǎng)的PAT真題,就可以領(lǐng)取50元的PAT報(bào)名優(yōu)惠券。鏈接: https://www.nowcoder.com/pat
可選語言:c/c++,java,python等多種語言都可以。
參賽要求:無論是否是大學(xué)生,均可參加。
分組說明:PAT分為頂級(英文,3題)、甲級(英文,4題)、乙級(中文,5題)。滿分都是100分。
比賽時長:各組都是3小時。
比賽題型:各語言考的題目相同,而頂級、甲級、乙級各組考的題目都不同,只考編程題。
比賽地點(diǎn):線下考試,PAT目前有考點(diǎn) 70多處, 分布在 26 省/直轄市的 51 座城市中, 涉及合作院校 67 所。
比賽賽制:IOI賽制,即每道題提交之后都有反饋,可以看到“通過”、“運(yùn)行錯誤”、“答案錯誤”等等,甚至可以實(shí)時看到自己每道題得了多少分,根據(jù)每道題通過的測試點(diǎn)的數(shù)量可獲得相應(yīng)的分?jǐn)?shù)。每道題不限制提交次數(shù),僅以最后一次提交為準(zhǔn)。
往年真題(收費(fèi)):https://pintia.cn/market
練習(xí)系統(tǒng)(免費(fèi)):https://pintia.cn/problem-sets
獲獎:考試后會發(fā)成績單。浙江大學(xué)計(jì)算機(jī)學(xué)院與軟件學(xué)院還以PAT(甲級、頂級)一年內(nèi)的成績作為碩士研究生招生上機(jī)復(fù)試成績。另外很多企業(yè)對于PAT成績優(yōu)異者可以免機(jī)試、優(yōu)先錄取等,詳情見https://www.patest.cn/company
CCF CSP(CCF計(jì)算機(jī)軟件能力認(rèn)證,官網(wǎng):http://www.cspro.org/)
舉辦時間:從2014年開始每年舉辦3次,一般為每年3月(2020年因疫情推遲)、9月和12月。
報(bào)名時間:一般在每次考試前一兩個月開始報(bào)名。
報(bào)名費(fèi):非會員400元,會員200元。會員只需花50元就可以開通一年,一年內(nèi)三次認(rèn)證都可以享受會員價(最近辦會員好像暫停了)。
可選語言:C/C++、Java和Python。
參賽要求:無論是否是大學(xué)生,均可參加。
分組說明:無分組,每屆所有考生都考同一套題。
考試時長:4小時。
考試題型:5道題,都是編程題。一般難度按照題號遞增。
考試地點(diǎn):線下考試,在全國有80多個認(rèn)證點(diǎn)。
考試賽制:OI賽制,即每道題提交之后都沒有任何反饋,最后根據(jù)每道題通過的測試點(diǎn)的數(shù)量獲得相應(yīng)的分?jǐn)?shù)。每道題不限制提交次數(shù),僅以最后一次提交為準(zhǔn)。
往年真題:http://www.cspro.org/ ,注冊并登陸后,“報(bào)名考試”-“模擬考試”
獲獎:認(rèn)證結(jié)束3個工作日后可登陸官網(wǎng)查看成績,可下載打印帶紅色公章電子版成績單。有的學(xué)校將CSP成績作為畢業(yè)要求、保研要求或考研免機(jī)試條件等,有的公司對CSP成績優(yōu)異者優(yōu)先錄取。另外如果成績達(dá)到一定標(biāo)準(zhǔn)(各地區(qū)分?jǐn)?shù)要求不同),可報(bào)名參加CCF CCSP分賽區(qū)競賽、CCF CCSP競賽,報(bào)名需要另外收費(fèi)。
GPLT 團(tuán)體程序設(shè)計(jì)天梯賽(官網(wǎng):https://gplt.patest.cn/regulation)
舉辦時間:比賽時間一般安排在每年 3~5 月?lián)袢张e行,2020年是第5屆。
報(bào)名時間:一般在舉辦時間十天前截止。
報(bào)名費(fèi):競賽注冊費(fèi)為500元/隊(duì),會務(wù)費(fèi)為150元/人。
可選語言:C、C++ 和 Java。
參賽要求:需要由每個學(xué)校的老師注冊并申請隊(duì)伍后,學(xué)生才能報(bào)名,由老師帶隊(duì)參賽。每名參賽隊(duì)員必須是參賽隊(duì)所屬高等學(xué)校的在冊本科生或?qū)?粕?,每支參賽?duì)由最多 10 名隊(duì)員組成,每位參賽隊(duì)員使用一臺計(jì)算機(jī)獨(dú)立比賽。
分組說明:競賽分為 3 個組別:珠峰爭鼎(本科組)、華山論劍(本科組)、滄海競舟(專科組),本科生限參加 “華山論劍”組或“珠峰爭鼎”組;??粕蓞⒓尤我唤M。競賽中 3 個不同組別使用同一套題目,在同一時間,按照統(tǒng)一評分規(guī)則進(jìn)行比賽。
比賽時長:3個小時。
比賽題型:都是編程題。競賽題目分 3 個梯級:基礎(chǔ)級設(shè) 8 道題,其中 5 分、10 分、15 分、20 分的題各 2 道,滿分為 100 分;進(jìn)階級設(shè) 4 道題,每道題 25 分,滿分為 100 分;登頂級設(shè) 3 道題,每道題 30 分,滿分為 90 分。
比賽地點(diǎn):線下比賽,在全國有三四十個賽點(diǎn)。
比賽賽制:IOI賽制,即每道題提交之后都有反饋,可以看到“通過”、“運(yùn)行錯誤”、“答案錯誤”等等,甚至可以實(shí)時看到自己每道題得了多少分,根據(jù)每道題通過的測試點(diǎn)的數(shù)量獲得相應(yīng)的分?jǐn)?shù)。每道題不限制提交次數(shù),僅以最后一次提交為準(zhǔn)。
練習(xí)系統(tǒng):拼題A網(wǎng)站 https://pintia.cn(即比賽使用的在線自動判題系統(tǒng))提供包括往屆真題在內(nèi)的練習(xí)題目。是的,就是跟PAT同一個練習(xí)系統(tǒng)。
獲獎:競賽的 3 個組別分別設(shè)置全國高校獎、全國團(tuán)隊(duì)獎、個人特等獎、個人優(yōu)勝獎、特別獎、成功參賽獎;同時各省設(shè)置省內(nèi)高校獎和團(tuán)隊(duì)獎。詳見 https://gplt.patest.cn/regulation
傳智杯(官網(wǎng):http://dasai.ityxb.com/)
舉辦時間:每年舉辦1次,一般為每年3月或4月。2020年是第二屆。
報(bào)名時間:一般在前一年11月開始報(bào)名。
報(bào)名費(fèi):免費(fèi)。
可選語言:C/C++、Java和Python。
參賽要求:大賽面向中國高校所有專業(yè)的在校生(含高職、大專、本科及研究生),已畢業(yè)的學(xué)生不具備參賽報(bào)名資格。
分組說明:無分組,每屆所有考生都考同一套題。
比賽時長:3小時。
比賽題型:每場?賽共計(jì) 4 題,每道題根據(jù)難易度有不同的得分,答對題?數(shù)越多即得分越?,在得分相同的情況下,答題?時最短則排名越?。
比賽地點(diǎn):院校選拔賽為線上比賽,決賽為北京線下比賽(2020年因疫情均改為線上比賽)。
比賽賽制:ACM-ICPC 賽制,即每道題提交之后都有反饋,可以看到“通過”、“運(yùn)行錯誤”、“答案錯誤”等等,每道題必須通過所有的測試點(diǎn)才算通過,通過題數(shù)/分?jǐn)?shù)相同的情況下按照答題時間排名。每道題不限制提交次數(shù),但沒通過的話會有罰時,僅以最后一次提交為準(zhǔn)。
練習(xí)系統(tǒng):沒有公布往年真題,沒有自己的練習(xí)系統(tǒng),官方建議練習(xí)系統(tǒng)為計(jì)蒜客https://nanti.jisuanke.com/acm
獲獎:正式賽分為院校選拔賽和決賽。
院校選拔賽:根據(jù)排名,分設(shè)一等獎(5%)、二等獎(10%)、三等獎(20%)和優(yōu)秀獎(15%)各若干項(xiàng),都有榮譽(yù)證書。初賽 一、二等獎獲獎選手將有資格進(jìn)入決賽。
決賽:設(shè)一等獎(2%)、二等獎(3%)、三等獎(5%)各若干項(xiàng),總獲獎人數(shù)不超過總報(bào)名數(shù)的10%,都有榮譽(yù)證書。
全國高校計(jì)算機(jī)能力挑戰(zhàn)賽(官網(wǎng):http://www.ncccu.org.cn/index.html#jg)
報(bào)名時間:2019年是9月-11月報(bào)名。
報(bào)名費(fèi):60元。
可選語言:C/C++、Java和Python。
參賽要求:大賽的參賽對象是高校所有專業(yè)的在校生(含高職、大專、本科及研究生)。
分組說明:各語言科目分開比賽,題目根據(jù)所選語言系統(tǒng)自動生成。
比賽時長:區(qū)域賽為90分鐘,決賽為120分鐘。
命題范圍:命題范圍參考:基本語言知識、數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)(線性結(jié)構(gòu)、樹形結(jié)構(gòu)、圖結(jié)構(gòu))、算法基礎(chǔ)(如排序查找等算法,以及算法綜合應(yīng)用)等知識。
比賽題型: 題型為選擇題、程序閱讀(閱讀程序?qū)懡Y(jié)果)、程序設(shè)計(jì)(每題設(shè)置若干得分點(diǎn),按通過的得分點(diǎn)計(jì)分)。
比賽地點(diǎn):線上比賽。
比賽賽制:OI賽制,即每道題提交之后都沒有任何反饋,最后根據(jù)每道題通過的測試點(diǎn)的數(shù)量獲得相應(yīng)的分?jǐn)?shù)。每道題不限制提交次數(shù),僅以最后一次提交為準(zhǔn)。
練習(xí)系統(tǒng):沒有公布往年真題,沒有自己的練習(xí)系統(tǒng)。
獲獎:程序設(shè)計(jì)賽分為區(qū)域賽和決賽。
區(qū)域賽:根據(jù)各參賽科目排名,分設(shè)一等獎(5%)、二等獎(10%)、三等獎(20%)和優(yōu)秀獎(15%),都有榮譽(yù)證書。區(qū)域賽一、二等獎獲獎選手將有資格進(jìn)入決賽。
決賽:設(shè)一等獎(2%)、二等獎(3%)、三等獎(5%)各若干項(xiàng),總獲獎人數(shù)不超過總報(bào)名數(shù)的10%,都有榮譽(yù)證書。
軟考(計(jì)算機(jī)技術(shù)與軟件專業(yè)技術(shù)資格(水平)考試,官網(wǎng):http://www.ruankao.org.cn/)
舉辦時間:每年5月份、11月份舉辦兩次。
報(bào)名時間:各省報(bào)名時間不同。一般上半年為2、3月份報(bào)名,下半年為8、9月份報(bào)名。
歷史:計(jì)算機(jī)軟件資格考試在全國范圍內(nèi)已經(jīng)實(shí)施了二十多年,近十年來,考試規(guī)模持續(xù)增長,截止目前,累計(jì)報(bào)考人數(shù)約有五百萬人。
報(bào)名費(fèi):各省不同,幾十元到一百多元。
參賽要求:無要求。無論是否是大學(xué)生,都可以報(bào)名。報(bào)考任何級別不需要學(xué)歷、資歷條件。
分組說明:計(jì)算機(jī)軟件資格考試設(shè)置了27個專業(yè)資格,涵蓋5個專業(yè)領(lǐng)域, 3個級別層次(初級、中級、高級)。計(jì)算機(jī)專業(yè)的大學(xué)生一般報(bào)考“程序員”(初級)或“軟件設(shè)計(jì)師”(中級),可直接報(bào)考中級。
時長:考試包括上午場、下午場,都是2.5小時。
可選語言:下午場中有一道C語言的題目必考,另外選做一道C++或Java的題目。都是代碼填空題。
命題范圍:軟件工程(占比最大)、基本語言知識、數(shù)據(jù)結(jié)構(gòu)、算法、操作系統(tǒng)、計(jì)算機(jī)組成原理、數(shù)據(jù)庫、計(jì)算機(jī)網(wǎng)絡(luò)、編譯原理、設(shè)計(jì)模式等計(jì)算機(jī)專業(yè)知識,幾乎覆蓋了計(jì)算機(jī)專業(yè)本科的所有專業(yè)課。雖然命題范圍廣,但是題目都不難。
考試題型: 不考編程題。上午場都是選擇題,滿分75分。下午場都是填空題,滿分75分。
考試地點(diǎn):線下考試,全國各地都有考點(diǎn)。
往年真題:官方將往年真題整理出書,可自行購買。詳見 http://www.ruankao.org.cn/book
獲獎:需要上午場和下午場都達(dá)到45分以上,才能通過考試。通過之后可以領(lǐng)取到合格證書,詳見http://www.ruankao.org.cn/index/hg
學(xué)習(xí)資源推薦
https://oi-wiki.org
貼一下我用過的資料:
oj(Online Judge):
洛谷:https://www.luogu.com.cn/
(有完善的的題單,基本涵蓋所有熱門知識點(diǎn))
功能:
云剪切板
題庫
題單
acwing:https://www.acwing.com/about/
(主打付費(fèi)課程,質(zhì)量很高,有條件的話可以報(bào)一下)
??透傎悾篽ttps://ac.nowcoder.com/acm/home/542457559
(會時不時的舉辦比賽)
CF:https://codeforces.com/
(俄羅斯網(wǎng)站,題目質(zhì)量最高,舉辦比賽很頻繁,有積分系統(tǒng),可以檢驗(yàn)自己的水平)
c語言網(wǎng):https://www.dotcpp.com/oj/problemset.php?mark=6
(有藍(lán)橋杯的歷年題目)
藍(lán)橋杯官方練習(xí)系統(tǒng):https://lx.lanqiao.cn/
(感覺有點(diǎn)拉跨,數(shù)據(jù)不公開)
紙質(zhì)資料:
算法競賽入門經(jīng)典(紫書):難度較高,不太推薦
算法競賽進(jìn)階指南(藍(lán)書):難度較高,但是講解很詳細(xì),沖國賽用
啊哈算法:適合新手入門,有很多小人插圖,很有趣
深入淺出程序設(shè)計(jì)競賽:強(qiáng)推,配合洛谷題單使用
比賽鏈接
【藍(lán)橋杯】萌新首秀全國高校新生編程排位賽!點(diǎn)擊鏈接https://www.lanqiao.cn/oj-contest/ 選擇對應(yīng)場次準(zhǔn)時參賽文章來源:http://www.zghlxwxcb.cn/news/detail-728355.html
之前發(fā)的藍(lán)橋杯的新生賽名額我已經(jīng)申請下來了,登錄網(wǎng)站注冊認(rèn)證后,進(jìn)入比賽界面自己報(bào)名適合自己時間的就行文章來源地址http://www.zghlxwxcb.cn/news/detail-728355.html
到了這里,關(guān)于(入門向)面向萌新的算法比賽入門指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!