有史以來第一屆面向社會征題的NOIp結束了。最開始以為面向社會征題會很難,但是這是我參加的最水的一次NOIp了。
由於停了兩月的課,所以現在正在補文化科目就沒時間打代碼了。所以所有的題目就均不給出代碼了啦啦啦~為了方便沒有參加NOIP的童鞋們我把題目網址放到了每道題題解的最后。
晚了兩周的題解如下:
Day1T1 生活大爆炸版石頭剪刀布
我就不說了。。近幾年來NOIp最水的第一題(我會告訴你我去年第一題用的是30分算法?)我們這里有一位小伙伴本地測試AC,但是官方爆0了。我們特意下載了NOI Linux幫他重測,原因是什么呢?沒有#include<cstdio>就freopen+stdin。stdin是定義在cstdio里面的好嗎!!所以他第一天愉快的爆0。。但是第二天他神奇的加上了#include <fstream>,這個里面有定義stdin。。簡直沒話說。。另外他的D1T2和D1T3上交的是main.cpp,全部沒有收上去。不過收上去也是CE。。
感謝后世人,戒之慎勿忘!
一定養成檢查文件名、頭文件的好習慣!頭文件最好一開始就全部打上去,不管用不用得到。在此分享一下我的代碼模板:

1 #include <iostream> 2 #include <cstdio> 3 #include <fstream> 4 #include <cstring> 5 #include <string> 6 #include <cstdlib> 7 #include <cmath> 8 #include <algorithm> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 #include <list> 14 #include <vector> 15 #include <ctime> 16 #include <functional> 17 #include <iterator> 18 using namespace std; 19 typedef long long LL; 20 typedef unsigned int Uint; 21 const int INF=0x3fffffff; 22 //==============struct declaration============== 23 24 //==============var declaration================= 25 26 //==============function declaration============ 27 28 //==============main code======================= 29 int main() 30 { 31 #define FILE__ 32 #ifdef FILE__ 33 freopen("spyweb.in","r",stdin); 34 freopen("spyweb.out","w",stdout); 35 #endif 36 37 return 0; 38 } 39 //================fuction code====================
回到正題,n<=200,不同的人會有不同的做法:
普通青年:打表判斷獲勝關系。
文藝青年:將兩個外星人調換順序,那么就可以直接比較大小判斷勝負了。
二逼青年:16或者25個 if。。。。
http://218.28.19.228/cogs/problem/problem.php?pid=1803
Day1T2 聯合權值
30分算法:FLOYED算出每兩個點之間的距離,然后枚舉距離為2的點。算法復雜度O(n3)。
70分算法:對於每一個點,BFS向外擴展兩層。時間復雜度O(n2)。可以輕易的用菊花圖卡掉。(比如1號點直接鏈接9999個點)
100分算法:距離為2的點之間一定是有一個點的,我們對每個點進行維護,那么最后的答案就是每個點任意兩個孩子權值和的乘積,如果直接枚舉的話時間復雜度還是O(n2),我們這里用前序和優化,時間復雜度O(n)。
http://218.28.19.228/cogs/problem/problem.php?pid=1804
Day1T3 飛揚的小鳥
不知道為什么我總是喜歡把這一題叫做憤怒的小鳥。。
話說每年總是有廣告題。。選擇客棧,瑪雅游戲什么的我就不說了。。
30分算法:沒有管道的話。。我還沒想有什么算法0_0
50分算法:暴搜一點問題都沒有
70分算法:用f[x][h]表示飛到(x,h)這個地方最少要點幾次屏幕,那么動態轉移方程很好寫吧:
f[x+1][h+n*xi]=min{f[x+1][h+n*xi],f[x][h]+n}
f[x+1][h-yi]=min{f[x+1][h-yi],f[x][h]}
然后水管全部設置為INF就行,初值f[0][i]=0
時間復雜度O(n*m2)
100分算法:發現我們重復計算了很多次同一個狀態,這就導致轉移狀態的復雜度太高,所以我們把h mod xi相等的高度一起計算,時間復雜度優化到O(n*m)。
http://218.28.19.228/cogs/problem/problem.php?pid=1805
Day1總結:
還是挺水的,其實不知道各位是否看出來最后一題就是一個向上完全背包,向下0/1背包的模型。考試的時候沒能看出來有點可惜了。用的記憶化搜索,可能是因為有一些不能達到的狀態沒有走到的原因吧,有75分。
那么第一天275分拿到手了。第一天拿一個100/70/50是很容易的,那么就有220分了。
Day2T1 無線網絡發射器選址
為什么每天的第一題名字都是這么長。。
那么這里再用我的一個小伙伴的親身經歷告訴大家考試方法,那就是不作死就不會死。
很簡單的一題,枚舉每一個點作為放置路由器的地方,然后統計比較就行。時間復雜度O(128*128*n),針對最大n是20的范圍完全可以通過。
某個小伙伴認為他可以優化一下,寫了個前序和。。然后不知道哪里寫錯了。。70分還是60分來着。然后枚舉點只從(d,d)枚舉到(128-d,128-d)
其實能有這么多分都是萬幸了。。要我出數據就專門卡這些亂優化的。
還見到有人寫2維樹狀數組的= =吃飽了沒事做。。不過樹狀數組好在不容易寫錯。
http://218.28.19.228/cogs/problem/problem.php?pid=1806
Day2T2 尋找道路
看到這一題第一反應就是強聯通分量,想了15min才發現沙茶了O_o
30分算法:應該是給搜索的,但是我不知道怎么搜= =
60分算法:對於每一個點跑一邊BFS看看是否能夠到達終點,然后從起點BFS,避開那些不能到達終點的點。時間復雜度O(n2)。
或者是floyed判斷是否能到達終點似乎方便一些?時間也是夠用的。
100分算法:難道沒有發現對於每一個點BFS判斷是否能到達終點就等價於在反圖中從終點開始BFS?將不能到的點打上標記,然后正向BFS避開即可。時間富O(n)。
P.S.我看見了寫鄰接矩陣完美MLE的。
有想到正解的實力居然不知道開鄰接表也是醉了。。。還看到C++鄰接表寫掛的,Vector不能用嗎= =反正NOIp又不會卡你STL。
http://218.28.19.228/cogs/problem/problem.php?pid=1807
Day2T3 解方程
這個題我最開始就想到求導和二分法求根了。。怎么辦我沒救了!!
那么30分算法:n<=2不會我也沒辦法。。
50分算法:高精度強行1-m搞起,本來我是想寫這個的
70分算法1:高精度+FFT/高精度+秦九韶/高精度+秦九韶+FFT 然后1-m試一次。但是還是很難寫
70分算法2:將每一個系數均MOD一個大質數,就是計算該方程在模意義下的解。如果你怕不保險就多取幾個質數,不過據說這次沒有卡1e8+7和2^31-1這兩個質數,時間復雜度O(n*m)
100分算法1:我們知道,如果在模p意義下X不是方程的解,那么X+p一定也不是方程的解,我們選取20-30個10000左右的質數,這樣的話理論上可以優化到O(n*sqrt(m))
100分算法2:我們發現70分算法最后跑出來大概需要1.2S,說明是被卡常數了。於是我們位運算加速MOD過程,取2^32-1這個數比較好。雖然不是質數不過也還好。那么我們就讓unsigned int自然溢出可好。。這個方法沒有實踐過,不保證一定AC。
http://218.28.19.228/cogs/problem/problem.php?pid=1808
Day2總結:
也挺水的,Day2的基本分數應該是100/70/30,那么就是200分,加上Day1一共420分,在HN應該是踩線1等。
不過這只是保底分。。你Day2T3如果只是能想出30分算法也沒辦法是吧。。所以這次比賽一等在除了ZJ和GD應該不難。ZJ530,GD520只要你每天前兩題AC,第三題70也沒問題。
那么我是100/100/75/100/100/70,一共545分,HN一等。
HNOIへ!然后參加了HNOI之后估計就要滾粗了吧- -
滾回去准備中科大少年班啦~