NOIP魔導(dǎo)書(shū)#1 我想要杯檸檬茶

假裝檸檬茶

目標(biāo)

閱讀完這篇文章,你可能會(huì)了解到:

  1. 維X檸檬茶還不錯(cuò),智乃超可愛(ài).
  2. 讓程序相應(yīng)你的輸入,并輸出某些內(nèi)容
  3. 了解不同的變量類(lèi)型
  4. 如果邏輯結(jié)構(gòu)
  5. zhx的冰紅茶做題法
  6. NOIP題目格式

算法基本結(jié)構(gòu)

當(dāng)在做題時(shí),基本步驟是什么:

  1. 讀題.不讀題做個(gè)P.
  2. 思考.不思考做個(gè)P.
  3. 回答.不回答做個(gè)P.

同樣的,一個(gè)程序至少要包括后2個(gè)過(guò)程.而通常,程序會(huì)包括3個(gè)過(guò)程.如果你理解了意思,接下來(lái),開(kāi)始吧.


例1:請(qǐng)問(wèn)今天你要來(lái)點(diǎn)...

抱歉,rabbit house是去不了了,不過(guò)今天集訓(xùn)隊(duì)可以去開(kāi)封菜.教練報(bào)銷(xiāo)哦.

開(kāi)封菜有很多吃的,比如牛肉漢堡,雞肉漢堡,薯?xiàng)l,可樂(lè),各種高熱量食品,對(duì)身體賊好(霧).現(xiàn)在,你已經(jīng)能寫(xiě)hello, world了,搞一個(gè)點(diǎn)餐程序應(yīng)該不難.

輸入

第一行一個(gè)N,表示有N個(gè)人點(diǎn)餐.

接下來(lái)N行,每行一個(gè)數(shù)字.其中

  • 1 代表牛肉漢堡
  • 2 代表雞肉漢堡
  • 3 代表薯?xiàng)l

輸出

對(duì)于每一個(gè)人,你需要輸出單獨(dú)一行,共N行,每行為其點(diǎn)餐的中文名.

范圍

  • 對(duì)于30%,0 < N < 10000
  • 對(duì)于100%,0 < N < 1000000

啊哈,第一道題

"應(yīng)該不難"這種說(shuō)法,絕對(duì)是坑,請(qǐng)記住.

現(xiàn)在暫時(shí)簡(jiǎn)化這道題:假設(shè)集訓(xùn)隊(duì)的同學(xué)賊懶,他們打算讓教練把所有人的吃的一起帶回來(lái).

這樣點(diǎn)餐的就只有1個(gè)人了.(笑)

如同做別的題一樣,讀題是必須的.而且人們會(huì)發(fā)現(xiàn),OI的題目背景都相當(dāng)?shù)挠腥?它總是試圖去模擬一個(gè)喜聞樂(lè)見(jiàn)的現(xiàn)實(shí)情況,讓人們會(huì)心一笑.有時(shí)也會(huì)在題目里玩梗.各位可愛(ài)的出題人小哥哥小姐姐的腦洞都是很大的,如果沒(méi)有他們,OI也許也會(huì)充斥著無(wú)聊的經(jīng)驗(yàn)技巧類(lèi)題目...可沒(méi)有暗指什么東西哦.

...

順便這給抽象問(wèn)題帶來(lái)很大麻煩.尤其是一些出題人套背景毫無(wú)藝術(shù)感,題目會(huì)變得很惡心.

思路

太簡(jiǎn)單了,你懂得.


魔法導(dǎo)入:輸入?

為了解決這個(gè)例題,獲取客戶(hù)的點(diǎn)餐是必要的.

輸入設(shè)備有很多,例如鍵盤(pán),鼠標(biāo),掃描儀,攝像頭,以及通過(guò)這些輸入設(shè)備輸入的預(yù)先保存的數(shù)據(jù).針對(duì)這些輸入,有不同的獲取方式.

比賽中(注意不單單NOIP比賽),常見(jiàn)的輸入方式是標(biāo)準(zhǔn)輸入文件輸入.如何獲取鼠標(biāo),攝像頭,掃描儀一類(lèi)的輸入,請(qǐng)搜索.或者,等我?guī)兹f(wàn)年更新一次添加上.

標(biāo)準(zhǔn)輸入

這個(gè)概念存在于shell.shell會(huì)打開(kāi)3個(gè)標(biāo)準(zhǔn)文件,分別為標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯(cuò)誤輸出

不同于windows.在windows下,文件可能是指圖片,文檔,表格,網(wǎng)頁(yè),游戲存檔...但是屏幕就是屏幕,cpu就是cpu,鼠標(biāo)就是鼠標(biāo).而在linux下,文件這個(gè)概念并不是只指文件,它可能是電腦的某些硬件!linux將操縱和讀取硬件屬性抽象成對(duì)一類(lèi)特殊的文件的操作.

對(duì)的,如果你想操縱硬件,只需要讀寫(xiě)文件!比起windows是不是很有趣?實(shí)際上,linux原本是希望將所有的硬件都表示成文件,可惜在實(shí)際使用上,全面貫徹這種做法不明智,往往在某些情況下,仍然將硬件特殊處理更方便.因此,linux有所取舍.

的確有系統(tǒng)把所有東西都當(dāng)作文件,可以了解一下plan 9.可以回頭跟別人裝嗶

獲取標(biāo)準(zhǔn)輸入,需要

  1. 引入適當(dāng)頭文件,在不同的頭文件里有獲取不同輸入的方法
  2. 從輸入流中得到輸入

頭文件?

這是c++組織代碼的一種方法.想像一下,總不能把10w行代碼寫(xiě)在一個(gè)文件里.當(dāng)把它們拆開(kāi)保存到不同文件里而且還要再進(jìn)行管理時(shí),頭文件就誕生了.頭文件的作用即是通過(guò)預(yù)編譯指令(下方)將散落在不同文件內(nèi)的代碼鏈接起來(lái).在C++中存在如此的幾種文件.了解就行,競(jìng)賽中用不上.

  • .cpp/.cxx 這類(lèi)文件中保存代碼的實(shí)現(xiàn).
  • .h 這類(lèi)文件中保存聲明,同時(shí)鏈接實(shí)現(xiàn).c++中的聲明和實(shí)現(xiàn)可以分離,聲明即表示"我們有這個(gè)功能",實(shí)現(xiàn)顧名思義.如此安排自有其道理.
  • .hpp 實(shí)現(xiàn)與聲明在同一文件內(nèi)的新格式.目的是為了減少引用的文件數(shù)目.

現(xiàn)在你不用過(guò)多的擔(dān)憂(yōu)什么功能在什么里,在接下來(lái)你總會(huì)漸漸記住,也會(huì)有一個(gè)專(zhuān)門(mén)的表格記載重要的頭文件.

像剛剛說(shuō)的,注意!

  • ==標(biāo)準(zhǔn)輸入輸出(standard I/O)在頭文件iostream內(nèi).==

在代碼開(kāi)頭寫(xiě)如下代碼引入

#include <iostream>

using namespace std;

#include <>是引入某個(gè)頭文件的命令,這行代碼引入了iostream(input/output stream).

我聽(tīng)說(shuō)還有#include ""

對(duì)的.它們的不同體現(xiàn)在查找這個(gè)文件位置的順序.使用<>會(huì)優(yōu)先尋找標(biāo)準(zhǔn)庫(kù),而""會(huì)優(yōu)先搜索你編寫(xiě)的代碼.至于有毛線(xiàn)用,你可以自己想象,或者未來(lái)能用上的話(huà),會(huì)說(shuō).標(biāo)準(zhǔn)庫(kù)這個(gè)概念將會(huì)在今后漸漸說(shuō)起.

我聽(tīng)說(shuō)#開(kāi)頭的代碼有特殊作用

不錯(cuò),聽(tīng)說(shuō)的很多,能不能把你聽(tīng)說(shuō)的途徑告訴我.以#開(kāi)頭的代碼叫做預(yù)編譯指令,它將告訴編譯器該如何處理你編寫(xiě)的代碼.還有很多預(yù)編譯指令將會(huì)在后面被介紹.

那行using是啥?

你先這么用著.在競(jìng)賽范圍內(nèi),你不需要這個(gè)知識(shí).但你問(wèn)的好.

1班和2班里都有一個(gè)小孩子叫小明,如何區(qū)分他們?人們于是稱(chēng)他們1班小明2班小明.在程序里,往往也有這種問(wèn)題.如果有多個(gè)人同時(shí)給自己的程序起名叫小明,就會(huì)導(dǎo)致問(wèn)題.為了避免這種麻煩,cpp有名字空間的概念.張三和李四寫(xiě)的程序分別放進(jìn)各自的空間,不就如同分班一樣解決了沖突嗎?

using namespace xxx就是聲明:在你寫(xiě)的程序里,允許xxx內(nèi)的東西全部攙和進(jìn)來(lái).

彈丸里有七海,櫻花莊里也有七海,到底哪個(gè)是哪個(gè)呢?不管了,反正都很可愛(ài).

引用之后,我們獲得了特多的方法和結(jié)構(gòu).其中,有一個(gè)叫做cin.意義可能為c系的輸入(in),用于獲取標(biāo)準(zhǔn)輸入.

使用如下代碼獲取客戶(hù)點(diǎn)的餐.

int order;
cin >> order;

第一行代碼創(chuàng)建(聲明)一個(gè)可以保存整數(shù)的變量(int),它的名字叫order.

==在C++中,聲明一個(gè)變量的語(yǔ)法如<type> <name>.必須記住.==

通用替換法

在魔導(dǎo)書(shū)里,通常使用<描述>來(lái)標(biāo)記一個(gè)必須填寫(xiě)的空格.使用[描述]來(lái)表示一個(gè)可以忽略不寫(xiě)的空格.

這個(gè)標(biāo)準(zhǔn)事先存在,并不是魔導(dǎo)書(shū)瞎創(chuàng)的.

這玩意和數(shù)學(xué)的變量有啥關(guān)系?

emmm它和數(shù)學(xué)的變量還稍稍有區(qū)別.最好別把它們混在一起.

第二行使用>>操作符從cin中取出一個(gè)輸入并存入order.

其實(shí)它還挺象形的不是嗎.

==cin就是iostream中提供的讀取標(biāo)準(zhǔn)輸入的結(jié)構(gòu)==,它就是這個(gè)名字,永遠(yuǎn)是,不管在哪都是.記住.

魔法導(dǎo)入:賦值

你可能在數(shù)學(xué)里見(jiàn)過(guò)這個(gè)神奇的字眼.但最好別把他們混在一起.

在c++中,賦值意味著,將一個(gè)值賦給一個(gè)變量,使用=運(yùn)算符.

對(duì),=并不表示相等,而是賦值,搞清楚.==才表示判斷相等.

觀察下面的代碼.

order = 1;
order = 2;
order = 3;
order = (1==2);

代碼依次使得order中存儲(chǔ)1,2,3,(下方揭曉).

魔法預(yù)導(dǎo)入:運(yùn)算

先扔掉這個(gè)題.嘿,既然我們讀入了一個(gè)整數(shù),可不可以對(duì)它加加減減?

你先造個(gè)計(jì)算器算算帳也不是不可以.

運(yùn)算由運(yùn)算符提供.c++支持加減乘除基本運(yùn)算(抱歉,不支持乘方),以及一些在計(jì)算機(jī)上特有的運(yùn)算.你可能能猜到了怎么表示,但現(xiàn)在我們不討論.

魔法導(dǎo)入:邏輯結(jié)構(gòu)-if

現(xiàn)在我們有客戶(hù)的點(diǎn)餐代號(hào)了,該怎么判斷它是哪個(gè)套餐?

判斷相等

顯然要把代號(hào)和已知的套餐編碼對(duì)比,找出相同的.

如何對(duì)比?

使用<1> == <2>.它會(huì)對(duì)比<1><2>.

注意,不能像數(shù)學(xué)那樣寫(xiě)<1> == <2> == <3>,這在C++中是不允許的.如何轉(zhuǎn)化將在運(yùn)算一篇介紹.

上不同的餐

正式介紹if.搭配==,if能夠在相等或者不等時(shí)執(zhí)行不同的代碼,將它用來(lái)處理點(diǎn)餐正好.

if (判斷) //成立那么就執(zhí)行這一條代碼

if (判斷) {
    //成立那么就執(zhí)行
}

if (判斷) {
    //成立那么就執(zhí)行
} else {
    //不成立那么就執(zhí)行
}

if (判斷) {
    //成立那么就執(zhí)行
} else if (另一個(gè)判斷) {
    //上一個(gè)if不成立但這個(gè)成立那么就執(zhí)行
} else {
    //2個(gè)都不成立就執(zhí)行
}

可見(jiàn)if的結(jié)構(gòu)可以說(shuō)比較復(fù)雜了,它的結(jié)構(gòu)差不多就上面那些.

if為一個(gè)固定的關(guān)鍵字,此后緊跟一個(gè)小括號(hào),小括號(hào)內(nèi)填寫(xiě)一段判斷(比如用==連接的判斷).而后跟隨一段代碼,if將會(huì)在判斷成立時(shí)才運(yùn)行這段代碼.

大括號(hào){}表示一塊代碼段,實(shí)際上可以在"任何"地方使用{}圈出一塊區(qū)域?qū)懘a.跟隨在if身后的{}代碼段被if所影響.

避免使用第一種格式

使用第一種格式容易造成理解上的困難(不是說(shuō)它難看...你會(huì)明白的),在使用時(shí)要三思.

注釋

為了更好的理解代碼,在代碼中,你可以使用注釋來(lái)解釋某些代碼的意思(是給人看的).它們不會(huì)對(duì)程序產(chǎn)生任何影響.

  • 使用//來(lái)開(kāi)始一段注釋.可以在新的一行或者每行的結(jié)尾.
  • 使用/* [注釋] */來(lái)圈起一大段可以跨行的注釋

作用域

如果你想了解更多的話(huà),{}實(shí)際上并不是圈出一段區(qū)域?qū)懘a這么簡(jiǎn)單.在c++中,{}同時(shí)圈出了一個(gè)作用域.作用域內(nèi)的聲明會(huì)覆蓋掉作用域外的聲明.意思就是,一旦在新的作用域內(nèi)創(chuàng)建了一個(gè)已經(jīng)存在的變量或者函數(shù),那么在這個(gè)作用域內(nèi)就只能使用新創(chuàng)建的了.同時(shí),在代碼執(zhí)行出作用域后,作用域內(nèi)創(chuàng)建的東西都會(huì)被銷(xiāo)毀.(嚴(yán)格來(lái)說(shuō),是創(chuàng)建在棧上的東西將被銷(xiāo)毀,但暫時(shí)不需要管這么多)

可我就是想管

行行行,管管管.在程序運(yùn)行時(shí),內(nèi)存被劃分為2個(gè)不同的區(qū)域.一個(gè)是棧,一個(gè)是堆.棧是有限的且快,堆是無(wú)限的且慢.按照上面解釋的變量創(chuàng)建方法<type> <name>;創(chuàng)建的基本類(lèi)型變量都存儲(chǔ)在棧上,并會(huì)在作用域結(jié)束后自動(dòng)銷(xiāo)毀.與自動(dòng)相對(duì)應(yīng)的自然就是不自動(dòng),在堆上創(chuàng)建的東西必須手動(dòng)銷(xiāo)毀才能釋放掉內(nèi)存.

將它寫(xiě)成餐點(diǎn)判斷

if (order == 1) {
    //點(diǎn)餐是牛肉漢堡
} else if (order == 2) {
    //點(diǎn)餐是雞肉漢堡
} else if (order == 3) {
    //點(diǎn)餐是薯?xiàng)l
} else {
    //點(diǎn)錯(cuò)了,沒(méi)這玩意
}

魔法導(dǎo)入:輸出

繼續(xù)我們的iostream,有了輸入了,自然也有輸出.

給你個(gè)機(jī)會(huì),根據(jù)cin的命名特點(diǎn)猜猜輸出是什么名字.別看了!先別看下面的內(nèi)容!猜完再看.

emmm,知道答案或者確定就是猜不出來(lái)的話(huà),使用鼠標(biāo)劃選下面的黑框框

(mmp居然不能寫(xiě)html代碼,那算了)

<html>
<a style="font-color:black;background-color:black;">cout</a>
</html>

和你猜的一樣嗎?是的,就是這種命名風(fēng)格.

cin相反的,向輸出流輸出內(nèi)容,使用<<.

為了不影響體驗(yàn),把這玩意放得向下點(diǎn).

.

.

.

.

.

.

.

.

.

cout << "牛肉漢堡" <<endl;

暫時(shí)將endl理解為換行(回車(chē))即可.

如果非想知道,cout內(nèi)部存在緩沖區(qū),endl的作用是輸出并清空緩沖區(qū)...這東西一展開(kāi)講就完蛋了,所以現(xiàn)在先停一停.

流的鏈?zhǔn)讲僮?/strong>

如同你看到的,在這行代碼里同時(shí)出現(xiàn)了兩個(gè)<<.對(duì)cincout的操作都可以如此同時(shí)使用多個(gè)>>``<<,想多少多少.

代碼

然后,這個(gè)點(diǎn)餐程序就是

#include <iostream>
using namespace std;

//正文開(kāi)始
int main() {
    int order;
    cin >> order;
    if (order == 1) {
        cout << "牛肉漢堡" <<endl;
    } else if (order == 2) {
        //點(diǎn)餐是雞肉漢堡
        cout << "雞肉漢堡" <<endl;
    } else if (order == 3) {
        cout << "薯?xiàng)l" <<endl; //點(diǎn)餐是薯?xiàng)l
    } else {
        //點(diǎn)錯(cuò)了,沒(méi)這玩意
        cout << "你點(diǎn)的啥玩意,沒(méi)有,再見(jiàn)" <<endl;
    }
    
    return 0;
}

魔法導(dǎo)入:emmmmm多出來(lái)一些東西-c++代碼結(jié)構(gòu)

你注意到上面的代碼多出來(lái)一些東西.在此統(tǒng)一解釋.

c++的程序大概分為2段,預(yù)編譯指令和正文.

在正文部分,出現(xiàn)了莫名其妙的

int main() {

代碼需要有一個(gè)啟動(dòng)的位置.到底該從什么地方開(kāi)始執(zhí)行代碼?這個(gè)函數(shù)給出了開(kāi)始的位置,關(guān)于它更多的內(nèi)容在之后講解.

一睹為快

函數(shù)就是一個(gè)大箱子,把一段常用的代碼(比如算乘方)封起來(lái),方便重復(fù)使用.
main()不止提供啟動(dòng)的位置,同時(shí)會(huì)傳遞啟動(dòng)的命令行參數(shù).

運(yùn)行

至此,代碼就寫(xiě)完了.可以運(yùn)行了.

打開(kāi)一個(gè)shell,輸入

$ g++ <filename>.cpp -o <filename>
$ ./<filename>

按理來(lái)說(shuō),只要你編寫(xiě)無(wú)誤,就可以在這之后按一個(gè)數(shù)字再回車(chē),程序會(huì)告訴你你點(diǎn)了什么.

命令行格式

在上面的命令中,每行前都帶有一個(gè)$.它表示一段命令的開(kāi)始,請(qǐng)忽略掉,不要一同輸入.

類(lèi)似的還有#.二者有不同的含義,但是對(duì)我們來(lái)說(shuō)沒(méi)啥用.

結(jié)

實(shí)際上,你可能只會(huì)了目標(biāo)里的一點(diǎn)點(diǎn).
其他的會(huì)說(shuō)的.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 首先,設(shè)計(jì)師要做的事情就是知道:簡(jiǎn)約不只是一種設(shè)計(jì)風(fēng)格.。 我認(rèn)為許多設(shè)計(jì)師認(rèn)為簡(jiǎn)約只是一種設(shè)計(jì)風(fēng)格。其實(shí)不是那樣...
    UIPark閱讀 250評(píng)論 0 0
  • 周檢視】2018.07.22在公司 易效能-200/201期-AC/I組-張奎林 沒(méi)有反思的人生不值得過(guò)-蘇格拉底...
    追風(fēng)cc閱讀 106評(píng)論 0 0
  • 班級(jí) :14303班 一 22G ...
    warthing閱讀 294評(píng)論 0 4

友情鏈接更多精彩內(nèi)容