標籤:style blog http color 使用 io 資料 for
09年的題總體來說 沒有難題,但是每道題除了第一題都要認真的慢慢寫才能AC,
第一題:
R國和S國正陷入戰火之中,雙方都互派間諜,潛入對方內部,伺機行動。
曆經艱險後,潛伏於S國的R國間諜小C終於摸清了S國軍用密碼的編碼規則:
1、 S國軍方內部欲發送的原資訊經過加密後在網路上發送,原資訊的內容與加密後所的內容均由大寫字母‘A’—‘Z’構成(無空格等其他字母)。
2、 S國對於每個字母規定了對應的“密字”。加密的過程就是將原資訊中的所有字母替換為其對應的“密字”。
3、 每個字母只對應一個唯一的“密字”,不同的字母對應不同的“密字”。“密字”可以和原字母相同。
例如,若規定‘A’的密字為‘A’,‘B’的密字為‘C’(其他字母及密字略),則原資訊“ABA”被加密為“ACA”。
現在,小C通過內線掌握了S國網路上發送的一條加密資訊及其對應的原資訊。小C希望能通過這條資訊,破譯S國的軍用密碼。小C的破譯過程是這樣的:掃描原資訊,對於原資訊中的字母x(代表任一大寫字母),找到其在加密資訊中的對應大寫字母y,並認為在密碼裡y是x的密字。如此進行下去直到停止於如下的某個狀態:
1、 所有資訊掃描完畢,‘A’—‘Z’所有26個字母在原資訊中均出現過並獲得了相應的“密字”。
2、 所有資訊掃描完畢,但發現存在某個(或某些)字母在原資訊中沒有出現。
3、 掃描中發現掌握的資訊裡有明顯的自相矛盾或錯誤(違反S過密碼的編碼規則)。例如某條資訊“XYZ”被翻譯為“ABA”就違反了“不同字母對應不同密字”的規則。
在小C忙得頭昏腦脹之際,R國司令部又發來電報,要求他翻譯另外一條從S國剛剛截取到的加密資訊。現在請你協助小C:通過內線掌握的資訊,嘗試破譯密碼。然後利用破譯的密碼,翻譯電報中的加密資訊。
解題過程:
1.直接類比,但是要理解題目“每個字母只對應一個唯一的“密字”,不同的字母對應不同的“密字”。“密字”可以和原字母相同”,也就是說 不同的字母有不同的密碼,不同的密碼也對應不同的字母,一開始由於沒考慮多個字母對應一個密碼的情況,不過過了90%的資料。
第二題:
Hanks博士是BT(Bio-Tech,生物技術)領域的知名專家,他的兒子名叫Hankson。現在,剛剛放學回家的Hankson正在思考一個有趣的問題。
今天在課堂上,老師講解了如何求兩個正整數c1和c2的最大公約數和最小公倍數。現在Hankson認為自己已經熟練地掌握了這些知識,他開始思考一個“求公約數”和“求公倍數”之類問題的“逆問題”,這個問題是這樣的:已知正整數a0,a1,b0,b1,設某未知正整數x滿足:
1、 x和a0的最大公約數是a1;
2、 x和b0的最小公倍數是b1。
Hankson的“逆問題”就是求出滿足條件的正整數x。但稍加思索之後,他發現這樣的x並不唯一,甚至可能不存在。因此他轉而開始考慮如何求解滿足條件的x的個數。請你協助他編程求解這個問題。
解題過程:
1.一開始打算打個素數表,但是資料很大,素數表沒法開很大,然後就一個個去除來分解質因數,雖然慢了點,但也能AC。將4個數都分解質因數,然後來確定x的每個質因子個數的上下界,利用乘法原理即可,由於沒開素數表,我儲存的方法也很麻煩。。一個字母打錯弄了半天。
2.AC之後想到其實可以打個素數表,開個50000以內的就好,因為資料最大20億,5w以上的質因數不可能有2個或2個以上,所以分解質因數的時候看最後剩下的數,如果不是1就必定是一個大素數,存下來就好。這樣使後面的演算法處理也方便得多。
第三題:
C國有n個大城市和m條道路,每條道路串連這n個城市中的某兩個城市。任意兩個城市之間最多隻有一條道路直接相連。這m條道路中有一部分為單向通行的道路,一部分為雙向通行的道路,雙向通行的道路在統計條數時也計為1條。 C國幅員遼闊,各地的資源分布情況各不相同,這就導致了同一種商品在不同城市的價格不一定相同。但是,同一種商品在同一個城市的買入價和賣出價始終是相同的。 商人阿龍來到C國旅遊。當他得知同一種商品在不同城市的價格可能會不同這一資訊之後,便決定在旅遊的同時,利用商品在不同城市中的價差賺回一點旅費。設C國n個城市的標號從1-n,阿龍決定從1號城市出發,並最終在n號城市結束自己的旅行。在旅遊的過程中,任何城市可以重複經過多次,但不要求經過所有n個城市。阿龍通過這樣的貿易方式賺取旅費:他會選擇一個經過的城市邁入他最喜歡的商品——水晶球,並在之後經過的另一個城市賣出這個水晶球。用賺取的價差當作旅費。由於阿龍主要是來C國旅遊,他決定這個貿易只進行最多一次。當然,在賺不到價差的情況下它就無需進行貿易。 假設C國有5個大城市,城市的編號和道路串連情況如,單向箭頭表示這條道路為單向通行。雙向箭頭表示這條道路為雙向通行。
假設1~n號城市的水晶球價格分別為4,3,5,6,1。 阿龍可以選擇如下一條線路:1->2->3->5,並在2號城市以3的價格買入水晶球,在3號城市以5的價格賣出水晶球,賺取的旅費數為2。 阿龍也可以選擇如下一條線路:1->4->5->4->5,並在第1次到達5號城市時以1的價格買入水晶球,在第2次到達4號城市時以6的價格賣出水晶球,賺取的旅費數為5。 現在給出n個城市的水晶球價格,m條道路的資訊(每條道路所串連的兩個城市的編號以及該條道路的通行情況)。請你告訴阿龍,他最多能賺錢多少旅費。
解題過程:
1.資料範圍很大,因此採用鄰接表儲存邊。。
2.演算法大致是:做兩次改造後的spfa,分別求出從1到i的最低貿易值和從i到n的最高貿易值,然後一個迴圈求出最大差值就是答案。。
spfa的過程大致如下:一開始寫將所有的d[i]賦值為a[i],但是這樣會使更新的過程斷掉,比如 a=4 3 2 5 1,各個城市連成一條鏈時,如果初始化d[i]=a[i],更新d[3]變成4後,
d[4]=5不能更新,就斷掉了,那麼d[n]就為1,實際應該是5.然後想到一開始把所有點都排入佇列,但這也是不行的。百度了一下,應該按下面這樣寫。
int cur; for (int i=1;i<n;i++) d[i]=-210000000; f=0; r=1; v[n]=1; q[0]=n; d[n]=a[n]; while (f!=r) { cur=q[f]; for (int c=head2[cur];c;c=edge2[c].nxt) { if (d[edge2[c].to]<d[cur]) { d[edge2[c].to]=d[cur]; if (v[edge2[c].to]) continue; q[r]=edge2[c].to; v[edge2[c].to]=1; r=(r+1)%n; } if (d[edge2[c].to]<a[edge2[c].to]) { d[edge2[c].to]=a[edge2[c].to]; if (v[edge2[c].to]) continue; v[edge2[c].to]=1; q[r]=edge2[c].to; r=(r+1)%n; } } v[cur]=0; f=(f+1)%n; }
第四題:
小城和小華都是熱愛數學的好學生,最近,他們不約而同地迷上了數獨遊戲,好勝的他們想用數獨來一比高低。但普通的數獨對他們來說都過於簡單了,於是他們向Z博士請教,Z博士拿出了他最近發明的“靶形數獨”,作為這兩個孩子比試的題目。 靶形數獨的方格同普通數獨一樣,在9格寬×9格高的大九宮格中有9個3格寬×3格高的小九宮格(用粗黑色線隔開的)。在這個大九宮格中,有一些數字是已知的,根據這些數字,利用邏輯推理,在其他的空格上填入1到9的數字。每個數字在每個小九宮格內不能重複出現,每個數字在每行、每列也不能重複出現。但靶形數專屬一點和普通數獨不同,即每一個方格都有一個分值,而且如同一個靶子一樣,離中心越近則分值越高。()
具體的分值分布是:最裡面一格(黃色地區)為10分,黃色地區外面的一圈(紅色地區)每個格子為9分,再外面一圈(藍色地區)每個格子為8分,藍色地區外面一圈(棕色地區)每個格子為7分,最外面一圈(白色地區)每個格子為6分,如所示。比賽的要求是:每個人必須完成一個給定的數獨(每個給定數專屬可能有不同的填法),而且要爭取更高的總分數。而這個總分數即每個方格上的分值和完成這個數獨時填在相應格上的數位乘積的總和。,在以下這個已經填完數位靶形數獨遊戲中,總分為2829。遊戲規定,將以總分數的高低決出勝負。
由於求勝心切,小城找到了善於編程的你,讓你幫他求出,對於給定的靶形數獨,能夠得到的最高分數。
解題過程:
1.首先想到只能是搜尋,但是搜尋量很大。加了個小剪枝,就是令所有剩下的還沒填的數都為9,如果這樣分數還比當前最優解小,就return。但是這個剪枝太不給力。。基本上用不到。
2.難以減少搜尋量,只能通過最佳化常數來解決。。就開了3個hash,記錄每行每列還有每個九宮格的數字使用方式,用二進位位元運算來存取。。還有一個判斷一個位置屬於哪個九宮格的小技巧(網路上看來的),就是一開始打個表,用一個二維數組儲存每個位置屬於哪個九宮格。。這樣能拿到80%的分。
3.然後就不知道該怎麼辦了。。各種騙的手段並用,先是填數字改成從大到小的順序,結果更慢。。然後用卡時器,結果WA了。。然後又試著從後往前倒著搜,加上卡時,終於AC,設定卡時的範圍蛋疼,提交n次才試出來,大概1500w能剛好AC。
4.據說有更好的解法,用了dancing link,可以參考部落格http://www.cnblogs.com/steady/archive/2011/03/15/1984791.html 學習一下。