我魔獸3終于AC啦

最近被程設(shè)的魔獸3折磨得很痛苦,終于AC了,所以慶祝一下發(fā)篇專欄。
我本來是從2改寫了一份的,但感覺越寫越爛,就放棄了原來的,重新寫了一遍。
我們還是先看下題目吧。
題目有點長,大家做好心理準(zhǔn)備】
E:魔獸世界三(開戰(zhàn))
總時間限制:?
2000ms?
內(nèi)存限制:?
65536kB
描述
魔獸世界的西面是紅魔軍的司令部,東面是藍(lán)魔軍的司令部。兩個司令部之間是依次排列的若干城市,城市從西向東依次編號為1,2,3 .... N ( N <= 20)。紅魔軍的司令部算作編號為0的城市,藍(lán)魔軍的司令部算作編號為N+1的城市。司令部有生命元,用于制造武士。
兩軍的司令部都會制造武士。武士一共有dragon?、ninja、iceman、lion、wolf?五種。每種武士都有編號、生命值、攻擊力這三種屬性。
雙方的武士編號都是從1開始計算。紅方制造出來的第n?個武士,編號就是n。同樣,藍(lán)方制造出來的第n?個武士,編號也是n。
武士在剛降生的時候有一個初始的生命值,生命值在戰(zhàn)斗中會發(fā)生變化,如果生命值減少到0(生命值變?yōu)樨?fù)數(shù)時應(yīng)當(dāng)做變?yōu)?處理),則武士死亡(消失)。
武士可以擁有武器。武器有三種,sword, bomb,和arrow,編號分別為0,1,2。
sword的攻擊力是使用者當(dāng)前攻擊力的20%(去尾取整)。
bomb的攻擊力是使用者當(dāng)前攻擊力的40%(去尾取整),但是也會導(dǎo)致使用者受到攻擊,對使用者的攻擊力是對敵人取整后的攻擊力的1/2(去尾取整)。Bomb一旦使用就沒了。
arrow的攻擊力是使用者當(dāng)前攻擊力的30%(去尾取整)。一個arrow用兩次就沒了。
武士降生后就朝對方司令部走,在經(jīng)過的城市如果遇到敵人(同一時刻每個城市最多只可能有1個藍(lán)武士和一個紅武士),就會發(fā)生戰(zhàn)斗。戰(zhàn)斗的規(guī)則是:
不同的武士有不同的特點。
編號為n的dragon降生時即獲得編號為n%3?的武器。dragon在戰(zhàn)斗結(jié)束后,如果還沒有戰(zhàn)死,就會歡呼。
編號為n的ninjia降生時即獲得編號為n%3?和(n+1)%3的武器。ninja?使用bomb不會讓自己受傷。
編號為n的iceman降生時即獲得編號為n%3?的武器。iceman每前進(jìn)一步,生命值減少10%(減少的量要去尾取整)。
編號為n的lion降生時即獲得編號為n%3?的武器。lion?有“忠誠度”這個屬性,其初始值等于它降生之后其司令部剩余生命元的數(shù)目。每前進(jìn)一步忠誠度就降低K。忠誠度降至0或0以下,則該lion逃離戰(zhàn)場,永遠(yuǎn)消失。但是已經(jīng)到達(dá)敵人司令部的lion不會逃跑。lion在己方司令部可能逃跑。
wolf降生時沒有武器,但是在戰(zhàn)斗開始前會搶到敵人編號最小的那種武器。如果敵人有多件這樣的武器,則全部搶來。Wolf手里武器也不能超過10件。如果敵人arrow太多沒法都搶來,那就先搶沒用過的。如果敵人也是wolf,則不搶武器。
以下是不同時間會發(fā)生的不同事件:
在每個整點,即每個小時的第0分, 雙方的司令部中各有一個武士降生。
紅方司令部按照iceman、lion、wolf、ninja、dragon?的順序制造武士。
藍(lán)方司令部按照lion、dragon、ninja、iceman、wolf?的順序制造武士。
制造武士需要生命元。
制造一個初始生命值為m?的武士,司令部中的生命元就要減少m?個。
如果司令部中的生命元不足以制造某本該造的武士,那就從此停止制造武士。
在每個小時的第5分,該逃跑的lion就在這一時刻逃跑了。
在每個小時的第10分:所有的武士朝敵人司令部方向前進(jìn)一步。即從己方司令部走到相鄰城市,或從一個城市走到下一個城市。或從和敵軍司令部相鄰的城市到達(dá)敵軍司令部。
在每個小時的第35分:在有wolf及其敵人的城市,wolf要搶奪對方的武器。
在每個小時的第40分:在有兩個武士的城市,會發(fā)生戰(zhàn)斗。
在每個小時的第50分,司令部報告它擁有的生命元數(shù)量。
在每個小時的第55分,每個武士報告其擁有的武器情況。
武士到達(dá)對方司令部后就算完成任務(wù)了,從此就呆在那里無所事事。
任何一方的司令部里若是出現(xiàn)了敵人,則認(rèn)為該司令部已被敵人占領(lǐng)。
任何一方的司令部被敵人占領(lǐng),則戰(zhàn)爭結(jié)束。戰(zhàn)爭結(jié)束之后就不會發(fā)生任何事情了。
給定一個時間,要求你將從0點0分開始到此時間為止的所有事件按順序輸出。事件及其對應(yīng)的輸出樣例如下:
1)?武士降生
輸出樣例:000:00 blue dragon 1 born
表示在0點0分,編號為1的藍(lán)魔dragon武士降生
如果造出的是lion,那么還要多輸出一行,例:
000:00 blue lion 1 born
Its loyalty is 24
表示該lion降生時的忠誠度是24
2) lion逃跑
輸出樣例:000:05 blue lion 1 ran away
表示在0點5分,編號為1的藍(lán)魔lion武士逃走
3)?武士前進(jìn)到某一城市
輸出樣例:
000:10 red iceman 1 marched to city 1 with 20 elements and force 30
表示在0點10分,紅魔1號武士iceman前進(jìn)到1號城市,此時他生命值為20,攻擊力為30
對于iceman,輸出的生命值應(yīng)該是變化后的數(shù)值
4) wolf搶敵人的武器
000:35 blue wolf 2 took 3 bomb from red dragon 2 in city 4
表示在0點35分,4號城市中,紅魔1號武士wolf?搶走藍(lán)魔2號武士dragon 3個bomb。為簡單起見,武器不寫復(fù)數(shù)形式
5)?報告戰(zhàn)斗情況
戰(zhàn)斗只有3種可能的輸出結(jié)果:
000:40 red iceman 1 killed blue lion 12 in city 2 remaining 20 elements
表示在0點40分,1號城市中,紅魔1號武士iceman?殺死藍(lán)魔12號武士lion后,剩下生命值20
000:40 both red iceman 1 and blue lion 12 died in city 2
注意,把紅武士寫前面
000:40?both red iceman 1 and blue lion 12 were alive in city 2
注意,把紅武士寫前面
6)?武士歡呼
輸出樣例:003:40 blue dragon 2 yelled in city 4
7)?武士抵達(dá)敵軍司令部
輸出樣例:001:10 red iceman 1 reached blue headquarter with 20 elements and force 30
(此時他生命值為20,攻擊力為30)對于iceman,輸出的生命值和攻擊力應(yīng)該是變化后的數(shù)值
8)?司令部被占領(lǐng)
輸出樣例:003:10 blue headquarter was taken
9)司令部報告生命元數(shù)量
000:50 100 elements in red headquarter
000:50 120 elements in blue headquarter
表示在0點50分,紅方司令部有100個生命元,藍(lán)方有120個
10)武士報告情況
000:55 blue wolf 2 has 2 sword 3 bomb 0 arrow and 7 elements
為簡單起見,武器都不寫復(fù)數(shù)形式。elements一律寫復(fù)數(shù),哪怕只有1個
交代武器情況時,次序依次是:sword,bomb, arrow。
輸出事件時:
首先按時間順序輸出;
同一時間發(fā)生的事件,按發(fā)生地點從西向東依次輸出.?武士前進(jìn)的事件,?算是發(fā)生在目的地。
在一次戰(zhàn)斗中有可能發(fā)生上面的?5?至?6?號事件。這些事件都算同時發(fā)生,其時間就是戰(zhàn)斗開始時間。一次戰(zhàn)斗中的這些事件,序號小的應(yīng)該先輸出。
兩個武士同時抵達(dá)同一城市,則先輸出紅武士的前進(jìn)事件,后輸出藍(lán)武士的。
對于同一城市,同一時間發(fā)生的事情,先輸出紅方的,后輸出藍(lán)方的。
顯然,8號事件發(fā)生之前的一瞬間一定發(fā)生了7號事件。輸出時,這兩件事算同一時間發(fā)生,但是應(yīng)先輸出7號事件
雖然任何一方的司令部被占領(lǐng)之后,就不會有任何事情發(fā)生了。但和司令部被占領(lǐng)同時發(fā)生的事件,全都要輸出。
在奇數(shù)編號城市,紅武士先發(fā)起攻擊
在偶數(shù)編號城市,藍(lán)武士先發(fā)起攻擊
戰(zhàn)斗開始前,雙方先對自己的武器排好使用順序,然后再一件一件地按順序使用。編號小的武器,排在前面。若有多支arrow,用過的排在前面。排好序后,攻擊者按此排序依次對敵人一件一件地使用武器。如果一種武器有多件,那就都要用上。每使用一件武器,被攻擊者生命值要減去武器攻擊力。如果任何一方生命值減為0或小于0即為死去。有一方死去,則戰(zhàn)斗結(jié)束。
雙方輪流使用武器,甲用過一件,就輪到乙用。某一方把自己所有的武器都用過一輪后,就從頭開始再用一輪。如果某一方?jīng)]有武器了,那就挨打直到死去或敵人武器用完。武器排序只在戰(zhàn)斗前進(jìn)行,戰(zhàn)斗中不會重新排序。
如果雙方武器都用完且都還活著,則戰(zhàn)斗以平局結(jié)束。如果雙方都死了,也算平局。
有可能由于武士自身攻擊力太低,而導(dǎo)致武器攻擊力為0。攻擊力為0的武器也要使用。如果戰(zhàn)斗中雙方的生命值和武器的狀態(tài)都不再發(fā)生變化,則戰(zhàn)斗結(jié)束,算平局。
戰(zhàn)斗的勝方獲得對方手里的武器。武士手里武器總數(shù)不超過10件。繳獲武器時,按照武器種類編號從小到大繳獲。如果有多件arrow,優(yōu)先繳獲沒用過的。
如果戰(zhàn)斗開始前雙方都沒有武器,則戰(zhàn)斗視為平局。如果先攻擊方?jīng)]有武器,則由后攻擊方攻擊。
輸入
第一行是t,代表測試數(shù)據(jù)組數(shù)
每組樣例共三行。
第一行,4個整數(shù) M,N,K, T。其含義為:
每個司令部一開始都有M個生命元( 1 <= M <= 100000)
兩個司令部之間一共有N個城市( 1 <= N <= 20 )
lion每前進(jìn)一步,忠誠度就降低K。(0<=K<=100)
要求輸出從0時0分開始,到時間T為止(包括T) 的所有事件。T以分鐘為單位,0 <= T <= 6000
第二行:五個整數(shù),依次是 dragon 、ninja、iceman、lion、wolf 的初始生命值。它們都大于0小于等于200
第三行:五個整數(shù),依次是 dragon 、ninja、iceman、lion、wolf 的攻擊力。它們都大于0小于等于200輸出
對每組數(shù)據(jù),先輸出一行:
Case n:
如對第一組數(shù)據(jù)就輸出 Case 1:
然后按恰當(dāng)?shù)捻樞蚝透袷捷敵龅綍r間T為止發(fā)生的所有事件。每個事件都以事件發(fā)生的時間開頭,時間格式是“時: 分”,“時”有三位,“分”有兩位。樣例輸入
樣例輸出
提示
請注意浮點數(shù)精度誤差問題。OJ上的編譯器編譯出來的可執(zhí)行程序,在這方面和你電腦上執(zhí)行的程序很可能會不一致。5 * 0.3 的結(jié)果,有的機(jī)器上可能是 15.00000001,去尾取整得到15,有的機(jī)器上可能是14.9999999,去尾取整后就變成14。因此,本題不要寫 5 * 0.3,要寫 5 * 3 / 10。
好了,我們終于看完題目了(笑)。
代碼在下面,有個問題的地方就是我仍然沒搞明白比較符號重載之后怎么調(diào)用,所以直接寫了一個指針的比較函數(shù)用在std::sort函數(shù)里了。
一共不到600行,挺讓我頭疼的。
(說實話不應(yīng)該直接往Github上丟嗎,放完這堆代碼現(xiàn)在打個字都卡)
注釋寫得比較完整了,大概還是比較易讀的。