1. 程式人生 > >NOIP2012普及組複賽解題報告

NOIP2012普及組複賽解題報告

【問題描述】

1.質因數分解

(prime.cpp/c/pas)

已知正整數 n 是兩個不同的質數的乘積,試求出較大的那個質數。

【輸入】

輸入檔名為 prime.in。 輸入只有一行,包含一個正整數 n

【輸出】

輸出檔名為 prime.out。 輸出只有一行,包含一個正整數 p,即較大的那個質數。

【輸入輸出樣例】 

prime.in

prime.out

21

7

【資料範圍】

對於 60%的資料,6 ≤ n ≤ 1000。 對於 100%的資料,6 ≤ n ≤ 2*109

 這題剛開始做的時候差點嚇死我了,10的9次方乘2啊!多麼大,可是,令我無語的是,資料太弱太弱,只要判斷第一個能被整除的數就OK了!

#include<iostream>

using namespace std;

int n;

int i;

int main()

{

freopen("prime.in","r",stdin);

freopen("prime.out","w",stdout);

cin>>n;

for(i=2;i<=n;i++)

if(n%i==0){cout<<n/i;break;}

return 0;

}

二、

【問題描述】


2.尋寶

(treasure.cpp/c/pas)

傳說很遙遠的藏寶樓頂層藏著誘人的寶藏。小明歷盡千辛萬苦終於找到傳說中的這個藏寶樓,藏寶樓的門口豎著一個木板,上面寫有幾個大字:尋寶說明書。說明書的內容如下:

藏寶樓共有 N+1 層,最上面一層是頂層,頂層有一個房間裡面藏著寶藏。除了頂層外, 藏寶樓另有 N 層,每層 M 個房間,這 M 個房間圍成一圈並按逆時針方向依次編號為 0,…, M-1。其中一些房間有通往上一層的樓梯,每層樓的樓梯設計可能不同。每個房間裡有一個指示牌,指示牌上有一個數字 x,表示從這個房間開始按逆時針方向選擇第 x 個有樓梯的房 間(假定該房間的編號為 k),從該房間上樓,上樓後到達上一層的 k 號房間。比如當前房間的指示牌上寫著 2,則按逆時針方向開始嘗試,找到第 2 個有樓梯的房間,從該房間上樓。 如果當前房間本身就有樓梯通向上層,該房間作為第一個有樓梯的房間。

尋寶說明書的最後用紅色大號字型寫著:“尋寶須知:幫助你找到每層上樓房間的指示 牌上的數字(即每層第一個進入的房間內指示牌上的數字)總和為開啟寶箱的金鑰”。

請幫助小明算出這個開啟寶箱的金鑰。

【輸入】

輸入檔案為 treasure.in

第一行 2 個整數 N M,之間用一個空格隔開。N 表示除了頂層外藏寶樓共 N 層樓,

M 表示除頂層外每層樓有 M 個房間。

接下來 N*M 行,每行兩個整數,之間用一個空格隔開,每行描述一個房間內的情況, 其中第(i-1)*M+j 行表示第 i j-1 號房間的情況(i=1, 2, …, Nj=1, 2, … ,M)。第一個整數 表示該房間是否有樓梯通往上一層(0 表示沒有,1 表示有),第二個整數表示指示牌上的數 字。注意,從 j 號房間的樓梯爬到上一層到達的房間一定也是 j 號房間。

最後一行,一個整數,表示小明從藏寶樓底層的幾號房間進入開始尋寶(注:房間編號 從 0 開始)。

【輸出】

輸出檔名為 treasure.out。 輸出只有一行,一個整數,表示開啟寶箱的金鑰,這個數可能會很大,請輸出對 20123

取模的結果即可。

【輸入輸出樣例】

treasure.in

treasure.out

2 3

1 2

0 3

1 4

0 1

1 5

1 2

1

5

【輸入輸出樣例說明】

第一層:

0 號房間,有樓梯通往上層,指示牌上的數字是 2

1 號房間,無樓梯通往上層,指示牌上的數字是 3

2 號房間,有樓梯通往上層,指示牌上的數字是 4; 第二層:

0 號房間,無樓梯通往上層,指示牌上的數字是 1

1 號房間,有樓梯通往上層,指示牌上的數字是 5

2 號房間,有樓梯通往上層,指示牌上的數字是 2

小明首先進入第一層(底層)的 1 號房間,記下指示牌上的數字為 3,然後從這個房間 開始,沿逆時針方向選擇第 3 個有樓梯的房間 2 號房間進入,上樓後到達第二層的 2 號房間, 記下指示牌上的數字為 2,由於當前房間本身有樓梯通向上層,該房間作為第一個有樓梯的 房間。因此,此時沿逆時針方向選擇第 2 個有樓梯的房間即為 1 號房間,進入後上樓梯到達頂層。這時把上述記下的指示牌上的數字加起來,即 3+2=5,所以開啟寶箱的金鑰就是 5

【資料範圍】

對於 50%資料,有 0<N≤10000<x≤10000

對於 100%資料,有 0<N≤100000<M≤1000<x≤1,000,000

純模擬+優化求mod

每次求和的時候加個%20123就O了

三、

【問題描述】


3.擺花

(flower.cpp/c/pas)

小明的花店新開張,為了吸引顧客,他想在花店的門口擺上一排花,共 m 盆。通過調 查顧客的喜好,小明列出了顧客最喜歡的 n 種花,從 1 n 標號。為了在門口展出更多種花, 規定第 i 種花不能超過 ai 盆,擺花時同一種花放在一起,且不同種類的花需按標號的從小到大的順序依次擺列。

試程式設計計算,一共有多少種不同的擺花方案。

【輸入】

輸入檔案 flower.in,共 2 行。

第一行包含兩個正整數 n m,中間用一個空格隔開。

第二行有 n 個整數,每兩個整數之間用一個空格隔開,依次表示 a1a2、……an

【輸出】

輸出檔名為 flower.out。 輸出只有一行,一個整數,表示有多少種方案。注意:因為方案數可能很多,請輸出

方案數對 1000007 取模的結果。

【輸入輸出樣例 1

flower.in

flower.out

2 4

3 2

2

【輸入輸出樣例說明】

2 種擺花的方案,分別是(1112)(1122)。括號裡的 1 2 表示兩種花, 比如第一個方案是前三個位置擺第一種花,第四個位置擺第二種花。

【資料範圍】

對於 20%資料,有 0<n≤80<m≤80≤ai≤8

對於 50%資料,有 0<n≤200<m≤200≤ai≤20

對於 100%資料,有 0<n≤1000<m≤1000≤ ai≤100

不想說了,水題一個,看到m,n,a[i],果斷3重迴圈,可以寫出動態轉移方程:f[i][j]=f[i][j]+f[i-1][j-k],是的,就是個揹包問題!

四、

【問題描述】


4.文化之旅

(culture.cpp/c/pas)

有一位使者要遊歷各國,他每到一個國家,都能學到一種文化,但他不願意學習任何一 種文化超過一次(即如果他學習了某種文化,則他就不能到達其他有這種文化的國家)。不 同的國家可能有相同的文化。不同文化的國家對其他文化的看法不同,有些文化會排斥外來 文化(即如果他學習了某種文化,則他不能到達排斥這種文化的其他國家)。

現給定各個國家間的地理關係,各個國家的文化,每種文化對其他文化的看法,以及這位使者遊歷的起點和終點(在起點和終點也會學習當地的文化),國家間的道路距離,試求 從起點到終點最少需走多少路。

【輸入】

輸入檔案 culture.in

第一行為五個整數 NKMST,每兩個整數之間用一個空格隔開,依次代表國家 個數(國家編號為 1 N),文化種數(文化編號為 1 K),道路的條數,以及起點和終點的編號(保證 S 不等於 T);

第二行為 N 個整數,每兩個整數之間用一個空格隔開,其中第 i 個數 Ci,表示國家 i

的文化為 Ci

接下來的 K 行,每行 K 個整數,每兩個整數之間用一個空格隔開,記第 i 行的第 j 個數 為 aijaij= 1 表示文化 i 排斥外來文化 ji 等於 j 時表示排斥相同文化的外來人),aij= 0 表示

不排斥(注意 i 排斥 j 並不保證 j 一定也排斥 i)。

接下來的 M 行,每行三個整數 uvd,每兩個整數之間用一個空格隔開,表示國家 u 與國家 v 有一條距離為 d 的可雙向通行的道路(保證 u 不等於 v,兩個國家之間可能有多條道路)。

【輸出】

輸出檔名為 culture.out。 輸出只有一行,一個整數,表示使者從起點國家到達終點國家最少需要走的距離數(如

果無解則輸出-1)。

【輸入輸出樣例 1

culture.in

culture.out

2 2 1 1 2

1 2

0 1

1 0

1 2 10

-1

【輸入輸出樣例說明】

由於到國家 2 必須要經過國家 1,而國家 2 的文明卻排斥國家 1 的文明,所以不可能到 達國家 2

【輸入輸出樣例 2

culture.in

culture.out

2 2 1 1 2

1 2

0 1

0 0

1 2 10

10

【輸入輸出樣例說明】

路線為 1 -> 2

【資料範圍】

對於 20%的資料,有 2≤N≤8K≤5

對於 30%的資料,有 2≤N≤10K≤5; 對於 50%的資料,有 2≤N≤20K≤8; 對於 70%的資料,有 2≤N≤100K≤10

對於 100%的資料,有 2≤N≤1001≤K≤1001≤M≤N21≤ki≤K1≤u, v≤N1≤d≤1000

S≠T1 ≤S, T≤N

有一點難度,可以有2種方法

1、動態規劃:用一個3維動態陣列,具體自己能推出來,當時也沒用這個。。。

2、二分+dijkstra 很容易的,找出就求。。。。。。。