第1題:找和為K的兩個元素
在一個長度為n(n < 1000)的整數序列中,判斷是否存在某兩個元素之和為k。
時間限制:1000
內存限制:65536
輸入
第一行輸入序列的長度n和k,用空格分開。 第二行輸入序列中的n個整數,用空格分開。
輸出
如果存在某兩個元素的和為k,則輸出yes,否則輸出no。
樣例輸入
9 10
1 2 3 4 5 6 7 8 9
樣例輸出
yes
要解決這個問題,可以使用雙重循環來遍歷所有可能的元素對,判斷它們的和是否等于給定的目標值k。
以下是解題的基本思路:
(1)讀取輸入的序列長度n和目標和k。
(2)創建一個長度為n的整數數組,用于存儲輸入的序列。
(3)使用一個外部循環,遍歷數組中的每個元素,假設當前元素為nums[i]。
(4)在外部循環內部,使用一個內部循環,從當前元素的下一個位置開始遍歷數組中的其他元素,假設當前元素為nums[j]。
(5)在內部循環中,判斷nums[i]和nums[j]的和是否等于目標和k。
-
如果相等,表示找到了一對元素的和為k,輸出"yes",并結束程序。
-
如果不相等,則繼續內部循環,遍歷下一個元素。
(6)如果遍歷完所有元素后仍未找到滿足條件的元素對,輸出"no"。
這個算法的時間復雜度為O(n^2),其中n為序列的長度。由于題目給出的時間限制為1000,這個算法在輸入規模不超過1000時可以在給定時間內解決問題。
下面是一個使用C語言編寫的解決方案:
#include <stdio.h>int main() {int n, k;scanf("%d %d", &n, &k);int nums[1000];for (int i = 0; i < n; i++) {scanf("%d", &nums[i]);}int found = 0;for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {if (nums[i] + nums[j] == k) {found = 1;break;}}if (found) {break;}}if (found) {printf("yes\n");} else {printf("no\n");}return 0;
}
這段代碼首先讀取輸入的序列長度n和目標和k,然后讀取n個整數到數組nums中。接下來,使用嵌套的for循環遍歷所有可能的元素對,判斷它們的和是否為k。如果找到一對和為k的元素,將found標記為1,并跳出循環。最后,根據found的值輸出結果。
請注意,根據題目的要求,序列長度n不會超過1000,因此我們在代碼中定義了一個長度為1000的數組nums來存儲輸入的整數序列。
第2題:Minecraft
Minecraft是一個幾乎無所不能的沙盒游戲,玩家可以利用游戲內的各種資源進行創造,搭建自己的世界。
在Minecraft中,基本的建筑元素是邊長為1個單位的立方體,Tony想用N個這種小立方體搭建一個長方體,并用他珍藏已久的貼紙對其進行裝飾。如果一張貼紙可以貼滿小立方體的一個面。那么,他需要用掉多少張貼紙呢?
時間限制:1000
內存限制:65536
輸入
一個整數N,表示小明所擁有的小立方體的個數。N不會超過1000。
輸出
一個整數,即小明最少用掉的貼紙有多少張。
樣例輸入
9
樣例輸出
30
這個問題可以通過計算來解決。我們知道一個長方體有6個面,每個面都需要用貼紙覆蓋。而每個面都由多個小立方體組成,每個小立方體需要用一張貼紙覆蓋。
以下是解題的基本思路:
(1)讀取輸入的小立方體的個數N。
(2)計算需要覆蓋的面的總數,即6個面的總和。
(3)將需要覆蓋的面的總數乘以N,得到所需的貼紙數量。
(4)輸出所需的貼紙數量。
以下是使用C語言編寫的解決方案:
#include <stdio.h>int main() {int N;scanf("%d", &N);int total_faces = 6; // 一個長方體有6個面int stickers = total_faces * N;printf("%d\n", stickers);return 0;
}
這段代碼首先讀取輸入的小立方體的個數N。然后,計算需要覆蓋的面的總數,即6個面的總和。最后,將需要覆蓋的面的總數乘以N,得到所需的貼紙數量。最后,輸出所需的貼紙數量。
根據題目的要求,小立方體的個數N不會超過1000,因此我們可以直接在計算過程中處理較大的數值。
第3題:踩方格
有一個方格矩陣,矩陣邊界在無窮遠處。我們做如下假設:
a. 每走一步時,只能從當前方格移動一格,走到某個相鄰的方格上;
b. 走過的格子立即塌陷無法再走第二次;
c. 只能向北、東、西三個方向走;
請問:如果允許在方格矩陣上走n步,共有多少種不同的方案。2種走法只要有一步不一樣,即被認為是不同的方案。
時間限制:1000
內存限制:65536
輸入
允許在方格上行走的步數n(n <= 20)
輸出
計算出的方案數量
樣例輸入
2
樣例輸出
7
這個問題可以使用遞歸的方式來解決。每一步可以選擇向北、東、西三個方向中的一個方向前進,然后在下一步中繼續做出相同的選擇,直到步數達到限制或無法再繼續移動為止。
以下是解題的基本思路:
(1)讀取輸入的允許在方格上行走的步數n。
(2)定義一個遞歸函數countPaths
,接受兩個參數:當前位置的坐標(x, y)和剩余步數remainingSteps。
(3)在遞歸函數中,首先判斷剩余步數是否為0,如果是則返回1,表示找到一種方案。
(4)否則,定義一個變量count
初始值為0,用于記錄方案數量。
(5)在遞歸函數中,分別遞歸調用countPaths
函數,傳入向北、東、西三個方向移動一步后的新坐標和剩余步數減1,將返回的結果累加到count
中。
(6)最后,返回count
作為當前位置和剩余步數的方案數量。
(7)在主函數中,調用countPaths
函數,傳入初始位置(0, 0)和允許的步數n,將返回的方案數量輸出。
以下是使用C語言編寫的解決方案:
#include <stdio.h>int countPaths(int x, int y, int remainingSteps) {if (remainingSteps == 0) {return 1;}int count = 0;count += countPaths(x, y + 1, remainingSteps - 1); // 向北移動一步count += countPaths(x + 1, y, remainingSteps - 1); // 向東移動一步count += countPaths(x - 1, y, remainingSteps - 1); // 向西移動一步return count;
}int main() {int n;scanf("%d", &n);int totalPaths = countPaths(0, 0, n);printf("%d\n", totalPaths);return 0;
}
這段代碼首先讀取輸入的允許在方格上行走的步數n。然后,定義了一個遞歸函數countPaths
來計算方案數量。在遞歸函數中,首先判斷剩余步數是否為0,如果是則返回1,表示找到一種方案。否則,定義一個變量count
用于記錄方案數量,并分別遞歸調用countPaths
函數,傳入向北、東、西三個方向移動一步后的新坐標和剩余步數減1,將返回的結果累加到count
中。最后,返回count
作為當前位置和剩余步數的方案數量。
在主函數中,調用countPaths
函數,傳入初始位置(0, 0)和允許的步數n,將返回的方案數量輸出。
根據題目的要求,允許在方格上行走的步數n不會超過20,因此遞歸的深度不會過大,可以在給定時間內解決問題。
第4題:蘋果消消樂
有100個蘋果和香蕉排成一條直線,其中有N個香蕉,你可以使用至多M次魔法道具將香蕉變成蘋果,最后“最長的連續蘋果數量”即為你本次蘋果消消樂的得分,給定蘋果和香蕉的排列,求你能獲得的最大得分。
時間限制:1000
內存限制:65536
輸入
第一行是一個整數T(1 <= T <= 10),代表測試數據的組數。 每個測試數據第一行是2個整數N和M(0 <= N, M <= 100)。第二行包含N個整數a1, a2, … aN(1 <= a1 < a2 < … < aN <= 100),表示第a1, a2, … aN個位置上擺放的是香蕉。
輸出
對于每組數據,輸出通過使用魔法道具后你能獲得的最大得分。
樣例輸入
3
5 1
34 77 82 83 84
5 2
10 30 55 56 90
5 10
10 30 55 56 90
樣例輸出
76
59
100
提示
這是個枚舉題
這個問題可以通過枚舉的方式來解決。我們可以遍歷每個位置,將其作為連續蘋果的起始位置,然后向后遍歷蘋果和香蕉的排列,同時記錄使用魔法道具的次數。在遍歷過程中,如果遇到香蕉,且還有剩余的魔法道具可用,則將香蕉變成蘋果,并增加得分。最后,找到最大的得分即可。
以下是解題的基本思路:
(1)讀取輸入的測試數據組數T。
(2)對于每組測試數據,讀取香蕉和蘋果的個數N和M。
(3)讀取N個整數,表示香蕉的位置。
(4)初始化最大得分maxScore為0。
(5)遍歷每個位置i作為連續蘋果的起始位置:
-
初始化當前得分score為0。
-
初始化剩余魔法道具次數remainingMagic為M。
-
遍歷位置j從i到100:
-
如果j是香蕉的位置且remainingMagic大于0,則將香蕉變成蘋果,增加得分score,并減少剩余魔法道具次數remainingMagic。
-
否則,增加得分score。
-
如果得分score大于最大得分maxScore,則更新最大得分maxScore。
-
(6)輸出最大得分maxScore。
以下是使用C語言編寫的解決方案:
#include <stdio.h>int main() {int T;scanf("%d", &T);while (T--) {int N, M;scanf("%d %d", &N, &M);int bananas[N];for (int i = 0; i < N; i++) {scanf("%d", &bananas[i]);}int maxScore = 0;for (int i = 0; i < 100; i++) {int score = 0;int remainingMagic = M;for (int j = i; j < 100; j++) {if (remainingMagic > 0 && j == bananas[score]) {remainingMagic--;score++;} else {score++;}if (score > maxScore) {maxScore = score;}}}printf("%d\n", maxScore);}return 0;
}
這段代碼首先讀取輸入的測試數據組數T。然后,對于每組測試數據,讀取香蕉和蘋果的個數N和M,以及N個整數表示香蕉的位置。接下來,初始化最大得分maxScore為0,并進行枚舉遍歷。在遍歷過程中,對于每個位置i作為連續蘋果的起始位置,初始化當前得分score為0和剩余魔法道具次數remainingMagic為M。然后,遍歷位置j從i到100,根據香蕉的位置和剩余魔法道具次數更新得分score,并更新最大得分maxScore。最后,輸出最大得分maxScore。
根據題目的要求,測試數據組數T不會超過10,枚舉的范圍在100內,因此可以在給定時間內解決問題。
第5題:流感傳染
有一批易感人群住在網格狀的宿舍區內,宿舍區為n*n的矩陣,每個格點為一個房間,房間里可能住人,也可能空著。在第一天,有些房間里的人得了流感,以后每天,得流感的人會使其鄰居傳染上流感,(已經得病的不變),空房間不會傳染。請輸出第m天得流感的人數。
時間限制:1000
內存限制:65536
輸入
第一行一個數字n,n不超過100,表示有n*n的宿舍房間。 接下來的n行,每行n個字符,’.’表示第一天該房間住著健康的人,’#’表示該房間空著,’@’表示第一天該房間住著得流感的人。 接下來的一行是一個整數m,m不超過100.
輸出
輸出第m天,得流感的人數
樣例輸入
5
…#
.#.@.
.#@…
#…
…
4
樣例輸出
16
這個問題可以使用廣度優先搜索(BFS)來解決。我們可以將所有初始感染的人作為起始節點,然后以它們為中心向外擴散,每次將感染傳播到相鄰的健康人,直到達到指定的天數。
以下是解題的基本思路:
(1)讀取輸入的宿舍房間大小n。
(2)創建一個n*n的二維字符數組rooms來表示宿舍房間的狀態。
(3)讀取n行字符,將它們存儲到rooms數組中。
(4)讀取指定的天數m。
(5)創建一個隊列,用于存儲當前感染的人的坐標。
(6)遍歷rooms數組,將初始感染的人的坐標加入隊列。
(7)創建一個整數變量infectedCount,并將其初始值設置為隊列的長度,表示初始感染的人數。
(8)創建一個整數變量days,并將其初始值設置為1,表示第一天。
(9)使用BFS算法進行傳播:
-
創建一個整數變量nextInfectedCount,用于記錄下一天感染的人數。
-
在循環中,從隊列中取出一個感染的人的坐標。
-
遍歷該人的相鄰人,如果相鄰的人是健康的,則將其感染,并將其坐標加入隊列。
-
每次遍歷一個感染的人的相鄰人后,將nextInfectedCount增加相應的數量。
-
如果隊列不為空,則表示還有感染的人未傳播完,將days增加1,更新infectedCount為nextInfectedCount。
-
如果隊列為空,則表示感染已經傳播完,退出循環。
(10)如果指定的天數m大于等于第一天,則根據m和第一天的差值,使用BFS算法繼續傳播,直到達到指定的天數。
(11)輸出最后一天感染的人數infectedCount。
以下是使用C語言編寫的解決方案:
#include <stdio.h>#define MAX_N 100typedef struct {int x;int y;
} Coordinate;int main() {int n;scanf("%d", &n);char rooms[MAX_N][MAX_N];for (int i = 0; i < n; i++) {scanf("%s", rooms[i]);}int m;scanf("%d", &m);int dx[] = {-1, 0, 1, 0};int dy[] = {0, 1, 0, -1};Coordinate queue[MAX_N * MAX_N];int front = 0;int rear = 0;for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (rooms[i][j] == '@') {Coordinate coord = {i, j};queue[rear++] = coord;}}}int infectedCount = rear;int days = 1;while (days < m) {int nextInfectedCount = 0;while (front < rear) {Coordinate current = queue[front++];for (int k = 0; k < 4; k++) {int nx = current.x + dx[k];int ny = current.y + dy[k];if (nx >= 0 && nx < n && ny >= 0 && ny < n && rooms[nx][ny] == '.') {rooms[nx][ny] = '@';Coordinate newCoord = {nx, ny};queue[rear++] = newCoord;nextInfectedCount++;}}}if (front == rear) {break;}days++;infectedCount += nextInfectedCount;}printf("%d\n", infectedCount);return 0;
}
這段代碼首先讀取輸入的宿舍房間大小n,并創建一個n*n的二維字符數組rooms來表示宿舍房間的狀態。然后,通過循環讀取n行這個問題可以通過廣度優先搜索(BFS)來解決。我們可以將感染的人作為起始點,然后以他們為中心向外擴散,每次將感染傳播到相鄰的健康人,直到達到指定的天數。