文章目錄
寫在前面
寫在前面:大家好!我是
ACfun
,我的暱稱來自兩個單詞Accepted
和fun
。我是一個熱愛ACM的蒟蒻。如果博客中有不足或者的錯誤的地方歡迎在評論區或者私信我指正,感謝大家的不吝賜教。我的唯一博客更新地址是:https://ac-fun.blog.csdn.net/。非常感謝大家的支持。一起加油,衝鴨!
用知識改變命運,用知識成就未來!加油 (ง •̀o•́)ง (ง •̀o•́)ง
本文轉載自亓官劼
試題 A: 指數計算
本題總分:5 分
【問題描述】
7 月 1 日是建黨日,從 1921 年到 2020 年,Communist Party of China已經帶領中國人民走過了 99 年。
請計算:7 ^ 2020 mod 1921,其中 A mod B 表示 A 除以 B 的餘數。
【答案提交】
這是一道結果填空題,你只需要算出結果後提交即可。本題的結果爲一個
整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
試題 A 題解
第一題大數問題
直接打開機器上的Python環境,直接算。
print((7**2020)%1921)
答案爲:480
試題 B: 解密
本題總分:5 分
【問題描述】
小明設計了一種文章加密的方法:對於每個字母 c,將它變成某個另外的
字符 Tc。下表給出了字符變換的規則:
字母c | Tc | 字母c | Tc | 字母c | Tc | 字母c | Tc |
---|---|---|---|---|---|---|---|
a | y | n | l | A | Y | N | L |
b | x | o | g | B | X | O | G |
c | m | p | o | C | M | P | O |
d | d | q | u | D | D | Q | U |
e | a | r | f | E | A | R | F |
f | c | s | s | F | C | S | S |
g | i | t | z | G | I | T | Z |
h | k | u | p | H | K | U | P |
i | n | v | w | I | N | V | W |
j | t | w | b | J | T | W | B |
k | j | x | r | K | J | X | R |
l | h | y | e | L | H | Y | E |
m | q | z | v | M | Q | Z | V |
例如,將字符串 YeRi 加密可得字符串 EaFn。小明有一個隨機的字符串,加密後爲EaFnjISplhFviDhwFbEjRjfIBBkRyY(由 30 個大小寫英文字母組成,不包含換行符),請問原字符串是多少?
(如果你把以上字符串和表格複製到文本文件中,請務必檢查複製的內容
是否與文檔中的一致。在試題目錄下有一個文件 str.txt,第一行爲上面的字符
串,後面 52 行依次爲表格中的內容。)
【答案提交】
這是一道結果填空題,你只需要算出結果後提交即可。本題的結果爲一個
只包含 30 個大小寫英文字母的字符串,在提交答案時只填寫這個字符串,填寫
多餘的內容將無法得分。
試題 B 題解
這裏如果有src.txt這個文件的話,可以直接寫個Python程序,讀入後輸入EaFnjISplhFviDhwFbEjRjfIBBkRyY,找出原字符即可。
這裏我沒那個文件,就直接複製表格了,粘貼的時候發現還是一行一行的來的,不過沒關係,這個字符串直接處理了就好了,Python程序爲:
s = 'aynlAYNLbxogBXOGcmpoCMPOddquDDQUearfEARFfcssFCSSgitzGITZhkupHKUPinvwINVWjtwbJTWBkjxrKJXRlhyeLHYEmqzvMQZV'
dir = {}
for i in range(len(s)):
if(i%2 == 1):
dir[s[i]] = s[i-1]
a = 'EaFnjISplhFviDhwFbEjRjfIBBkRyY'
for item in a:
print(dir[item],end='',sep='')
答案爲:YeRikGSunlRzgDlvRwYkXkrGWWhXaA
試題 C: 跑步訓練
本題總分:10 分
【問題描述】
小明要做一個跑步訓練。初始時,小明充滿體力,體力值計爲 10000。如果小明跑步,每分鐘損耗600 的體力。如果小明休息,每分鐘增加 300 的體力。體力的損耗和增加都是均勻變化的。
小明打算跑一分鐘、休息一分鐘、再跑一分鐘、再休息一分鐘……如此循
環。如果某個時刻小明的體力到達 0,他就停止鍛鍊。
請問小明在多久後停止鍛鍊。爲了使答案爲整數,請以秒爲單位輸出答案。
答案中只填寫數,不填寫單位。
【答案提交】
這是一道結果填空題,你只需要算出結果後提交即可。本題的結果爲一個
整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
試題 C 題解
這裏可以口算:答案爲:3880
10000 / (600-300) == 33.33
33*(600-300) = 9900
10000 - 9900 + 300 = 400 < 600
所以時間爲32*2*60 + 400/10 = 3880
也可以寫程序模擬:
energy = 10000
min = 0
second = 0
while(energy):
min += 1
if min % 2 == 1:
if energy > 600 :
energy -= 600
else:
min -= 1
second = energy/10
energy = 0
else:
energy += 300
if energy <= 0:
break
print(min*60+second)
答案:3380
試題 D: 合併檢測
本題總分:10 分
【問題描述】
新冠疫情由新冠病毒引起,最近在 A 國蔓延,爲了儘快控制疫情,A 國準備給大量民衆進病毒核酸檢測。然而,用於檢測的試劑盒緊缺。爲了解決這一困難,科學家想了一個辦法:合併檢測。即將從多個人(k個)採集的標本放到同一個試劑盒中進行檢測。如果結果爲陰性,則說明這 k個人都是陰性,用一個試劑盒完成了 k 個人的檢測。如果結果爲陽性,則說明至少有一個人爲陽性,需要將這 k 個人的樣本全部重新獨立檢測(從理論上看,如果檢測前 k 1 個人都是陰性可以推斷出第 k 個人是陽性,但是在實際操作中不會利用此推斷,而是將 k 個人獨立檢測),加上最開始的合併檢測,一共使用了 k + 1 個試劑盒完成了 k 個人的檢測。
A 國估計被測的民衆的感染率大概是 1%,呈均勻分佈。請問 k 取多少能最節省試劑盒?
【答案提交】
這是一道結果填空題,你只需要算出結果後提交即可。本題的結果爲一個
整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
試題D 題解
這題數學問題
設總人數爲pop,感染率p,每次k人,總市級數sum
sum = ([pop/k]+1)*(1+k*p(k+1))
這裏的[pop/k]+1)即pop/k向上取整
[pop/k]+1)這裏由於pop數量較大,所以這裏向上取整的1可以忽略,這裏直接取了pop/k,即
sum = (pop/k)*(1+kp(k+1))
將p代入sum = (pop/k)*(1+k*0.01(k+1))
sum求導 = (pop/k)(0.01k-1/k)
可得當k = 10時,sum取最小值
所以K = 10
答案:10
試題 E: REPEAT 程序
本題總分:15 分
【問題描述】
附件 prog.txt 中是一個用某種語言寫的程序。其中 REPEAT k 表示一個次數爲 k 的循環。循環控制的範圍由縮進表達,從次行開始連續的縮進比該行多的(前面的空白更長的)爲循環包含的內容。
例如如下片段:
REPEAT 2:
A = A + 4
REPEAT 5:
REPEAT 6:
A = A + 5
A = A + 7
A = A + 8
A = A + 9
A = A + 4 所在的行到 A = A + 8 所在的行都在第一行的循環兩次中。
REPEAT 6: 所在的行到 A = A + 7 所在的行都在 REPEAT 5: 循環中。
A = A + 5 實際總共的循環次數是 2 × 5 × 6 = 60 次。
請問該程序執行完畢之後,A 的值是多少?
【答案提交】
這是一道結果填空題,你只需要算出結果後提交即可。本題的結果爲一個
整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
試題 E 答案
這題直接按流程算也挺簡單
未說A初值,這裏默認爲0
REPEAT 6循環執行一次,A+30
REPEAT 5循環執行一次,A+185
REPEAT 2循環一次,A+4+185+8 = A+197
REPEAT 2循環後,A+394
最終:A+403
答案:403
試題 F: 分類計數
時間限制: 1.0s 內存限制: 512.0MB 本題總分:15 分
【問題描述】
輸入一個字符串,請輸出這個字符串包含多少個大寫字母,多少個小寫字
母,多少個數字。
【輸入格式】
輸入一行包含一個字符串。
【輸出格式】
輸出三行,每行一個整數,分別表示大寫字母、小寫字母和數字的個數。
【樣例輸入】
1+a=Aab
【樣例輸出】
1
3
1
【評測用例規模與約定】
對於所有評測用例,字符串由可見字符組成,長度不超過 100。
試題F 題解
C/C++描述程序爲:
#include <iostream>
using namespace std;
int main(){
string in;
cin>>in;
int num_digital,num_capital,num_lowercase;//數字,大寫字母,小寫字母的數量
num_capital = num_digital = num_lowercase = 0;
int len_in = in.length();
for(int i = 0;i < len_in;i++){
if(in[i] <= '9' && in[i] >= '0')
num_digital++;
if((in[i] <= 'Z' && in[i] >= 'A'))
num_capital++;
if(in[i] <= 'z' && in[i] >= 'a')
num_lowercase++;
}
cout<<num_capital<<endl<<num_lowercase<<endl<<num_digital;
return 0;
}
試題 G: 整除序列
時間限制: 1.0s 內存限制: 512.0MB 本題總分:20 分
【問題描述】
有一個序列,序列的第一個數是 n,後面的每個數是前一個數整除 2,請輸
出這個序列中值爲正數的項。
【輸入格式】
輸入一行包含一個整數 n。
【輸出格式】
輸出一行,包含多個整數,相鄰的整數之間用一個空格分隔,表示答案。
【樣例輸入】
20
【樣例輸出】
20 10 5 2 1
【評測用例規模與約定】
對於 80% 的評測用例,1 ≤ n ≤ 109。
對於所有評測用例,1 ≤ n ≤ 1018。
試題G 題解
簽到題
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
while(n){
cout<<n<<" ";
n/=2;
}
return 0;
}
試題 H: 走方格
時間限制: 1.0s 內存限制: 512.0MB 本題總分:20 分
【問題描述】
在平面上有一些二維的點陣。這些點的編號就像二維數組的編號一樣,從上到下依次爲第 1 至第 n 行,從左到右依次爲第 1 至第 m 列,每一個點可以用行號和列號來表示。現在有個人站在第 1 行第 1 列,要走到第 n 行第 m 列。只能向右或者向下走。
注意,如果行號和列數都是偶數,不能走入這一格中。
問有多少種方案。
【輸入格式】
輸入一行包含兩個整數 n, m。
【輸出格式】
輸出一個整數,表示答案。
【樣例輸入】
3 4
【樣例輸出】
2
【樣例輸入】
6 6
【樣例輸出】
0
【評測用例規模與約定】
對於所有評測用例,1 ≤ n ≤ 30, 1 ≤ m ≤ 30。
試題H 題解
數據量小直接暴力搜
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
vector<vector<int>> dp(n+1,vector<int>(m+1));
for(int i = 1;i <= n;i++){
dp[i][1] = 1;
}
for (int j = 1; j <= m; ++j) {
dp[1][j] = 1;
}
for(int i = 2;i <= n;i++){
for (int j = 2; j <= m; ++j) {
if(i%2==0 && j%2==0)
continue;
else
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
cout<<dp[n][m];
return 0;
}
試題 I: 字符串編碼
時間限制: 1.0s 內存限制: 512.0MB 本題總分:25 分
【問題描述】
小明發明瞭一種給由全大寫字母組成的字符串編碼的方法。對於每一個大寫字母,小明將它轉換成它在 26 個英文字母中序號,即 A → 1, B → 2, … Z →26。
這樣一個字符串就能被轉化成一個數字序列:比如 ABCXYZ → 123242526。
現在給定一個轉換後的數字序列,小明想還原出原本的字符串。當然這樣的還原有可能存在多個符合條件的字符串。小明希望找出其中字典序最大的字符串。
【輸入格式】
一個數字序列。
【輸出格式】
一個只包含大寫字母的字符串,代表答案
【樣例輸入】
123242526
【樣例輸出】
LCXYZ
【評測用例規模與約定】
對於 20% 的評測用例,輸入的長度不超過 20。
對於所有評測用例,輸入的長度不超過 200000。
試題I 題解
#include <iostream>
#include <vector>
using namespace std;
int main(){
string in ;
cin>>in;
int len = in.length();
string re = "";
int flag_1;//第一位爲1
int flag_2;//第一位爲2
flag_1 = flag_2 = 0;
for(int i = 0;i < len;i++){
if(flag_1){
int mid = int(in[i-1]-'0')*10+int(in[i]-'0');
re += char(mid+'A'-1);
flag_1 = 0;
continue;
}
if(flag_2){
if(in[i]<='6'){
int mid = int(in[i-1]-'0')*10+int(in[i]-'0');
re += char(mid+'A'-1);
flag_2 = 0;
} else{
re += char(in[i-1] - '0' +'A'-1);
re += char(in[i] - '0' +'A'-1);
flag_2 = 0;
}
continue;
}
if(in[i] >= '3')
re += char(in[i] - '0' + 'A' - 1);
if(in[i] == '1' ){
if(i+2<=len-1 && in[i] == '0'){
re += char(in[i] - '0' + 'A' - 1);
continue;
}
flag_1 = 1;
}
if(in[i] == '2'){
if(i+2<=len-1 && in[i] == '0'){
re += char(in[i] - '0' + 'A' - 1);
continue;
}
flag_2 = 1;
}
}
cout<<re;
return 0;
}
試題 J: 整數小拼接
時間限制: 1.0s 內存限制: 512.0MB 本題總分:25 分
【問題描述】
給定義個長度爲 n 的數組 A1, A2, · · · , An。你可以從中選出兩個數 Ai 和 Aj (i 不等於 j),然後將 Ai 和 Aj 一前一後拼成一個新的整數。例如 12 和 345 可以拼成 12345 或 34512 。注意交換 Ai 和 Aj 的順序總是被視爲 2 種拼法,即便是 Ai = Aj 時。
請你計算有多少種拼法滿足拼出的整數小於等於 K。
【輸入格式】
第一行包含 2 個整數 n 和 K。
第二行包含 n 個整數 A1, A2, · · · , An。
【輸出格式】
一個整數代表答案。
【樣例輸入】
4 33
1 2 3 4
【樣例輸出】
8
【評測用例規模與約定】
對於 30% 的評測用例,1 ≤ N ≤ 1000, 1 ≤ K ≤ 108, 1 ≤ Ai ≤ 104。
對於所有評測用例,1 ≤ N ≤ 100000,1 ≤ K ≤ 1010,1 ≤ Ai ≤ 109。