第十一屆藍橋杯省賽第一場原題


A:指數計算(5分)

【問題描述】

7月1日是建黨日,從1921年到2020年,中國XXX已經帶領中國人民走過了99年。
請計算:7^2020 mod 1921,其中A mod B 表示 A 除以 B 的余數。

【答案提交】

這是一道結果填空題,你只需要算出結果后提交即可。本題的結果為一個
整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。

【解題思路】

拿到這道題,我還想着用寫程序的方式去解決,寫程序咋寫呢,最開始想的就是在7乘的中間進行取余,為此我還找個小數手稿驗證了一下,但是結果是不對的,事后想想這樣確實不對。最后想到了以前用過分治的方式寫過階層求值,在合並的時候正好可以進行取余運算,正好求解了此問題。其實還有更簡單的,使用電腦的計算器就行,考試的時候還是要怎么簡單怎么做。

#include<iostream>
using namespace std;
int dfs(int n){
	if(n==1){
		return 7;
	}
	if(n%2==0){
		return (dfs(n/2)*dfs(n/2))%1921;
	}
	else if(n%2!=0){
		return (dfs(n/2)*dfs(n/2)*7)%1921;
	}
}
int main()
{
	cout << dfs(2020);
	return 0;
}

【答案】

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 個大小寫英文字母的字符串,在提交答案時只填寫這個字符串,填寫
多余的內容將無法得分

【解題思路】

這個問題就比較簡單了,就是簡單的字符串轉換,主要就是搞清楚字符的對應的關系。

#include<iostream>
#include<string>
using namespace std;
int main()
{
	//加密后字符串 
	string str="EaFnjISplhFviDhwFbEjRjfIBBkRyY";
	string s1="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	string s2="yxmdacikntjhqlgoufszpwbrevYXMDACIKNTJHQLGOUFSZPWBREV";
	for(int i=0;i<str.size();i++){
		int index = s2.find(str[i]);
		cout << s1[index];
	}
	return 0;
}

【答案】

YeRikGSunlRzgDlvRwYkXkrGWWhXaA

C:跑步訓練(10分)

【問題描述】

小明要做一個跑步訓練。
初始時,小明充滿體力,體力值計為 10000。如果小明跑步,每分鍾損耗
600 的體力。如果小明休息,每分鍾增加 300 的體力。體力的損耗和增加都是
均勻變化的。
小明打算跑一分鍾、休息一分鍾、再跑一分鍾、再休息一分鍾……如此循
環。如果某個時刻小明的體力到達 0,他就停止鍛煉。
請問小明在多久后停止鍛煉。為了使答案為整數,請以秒為單位輸出答案。
答案中只填寫數,不填寫單位。

【答案提交】

這是一道結果填空題,你只需要算出結果后提交即可。本題的結果為一個
整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。

【解題思路】

這題以前也接觸過類似的題,思路不難,將速度的單位化為秒,然后一秒鍾的走或者休息,直到體力達到0停止。

#include<iostream>
using namespace std;
int main()
{
	int sum=0;
	int n=10000;
	while(n>0){
		int t1=60;
		while(t1--&&n>0){
			n -= 10;
			sum++;
		}
		int t2=60;
		while(t2--&&n>0){
			n += 5;
			sum++;
		}
	}
	cout << sum;
	return 0;
}

【答案】

3880

D:合並檢測(10分)

【問題描述】

新冠疫情由新冠病毒引起,最近在 A 國蔓延,為了盡快控制疫情,A 國准 備給大量民眾進病毒核酸檢測。 然而,用於檢測的試劑盒緊缺。 為了解決這一困難,科學家想了一個辦法:合並檢測。即將從多個人(k 個)采集的標本放到同一個試劑盒中進行檢測。如果結果為陰性,則說明這 k 個人都是陰性,用一個試劑盒完成了 k 個人的檢測。如果結果為陽性,則說明 至少有一個人為陽性,需要將這 k 個人的樣本全部重新獨立檢測(從理論上看, 如果檢測前 k-1 個人都是陰性可以推斷出第 k 個人是陽性,但是在實際操作中 不會利用此推斷,而是將 k 個人獨立檢測),加上最開始的合並檢測,一共使用 了 k + 1 個試劑盒完成了 k 個人的檢測。 A 國估計被測的民眾的感染率大概是 1%,呈均勻分布。請問 k 取多少能 最節省試劑盒?

【答案提交】

這是一道結果填空題,你只需要算出結果后提交即可。本題的結果為一個 整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。

【解題思路】

這題實際上就是一道數學應用題,主要就是列出解題方程,題意說,A國有1%人感染,也就是說一個人患病的概率是1%,未患病的概率是99%,假如說說k=1時,那么必然消耗1個試劑盒,當k=2時,消耗(0.990.99)1+(0.990.01+0.010.99+0.010.01)3,那么規律也就出來了,k個人全部未患病概率為0.99k,存在患病概率為(1-0.99k),設k個人需要消耗w個試劑盒,可以列出如下的方程,

w=0.99k+(1-0.99k)*(k+1)

那么當不使用此方案時,需要使用k個試劑盒,最省試劑盒也就是w和k值之比最小。

w/k = 1-0.99k+1/k

可是這個k該咋算呢?

當1-0.99k和1/k相等時取最小值。

拿計算器大約算出一個k=11,不知道對不對。

【答案】

11

E:REPEAT程序(15分)

【問題描述】

附件 prog.txt 中是一個用某種語言寫的程序。
下載地址 :附件 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 的值是多少?

【答案提交】

這是一道結果填空題,你只需要算出結果后提交即可。本題的結果為一個
整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。

【解題思路】

這題暫時還不知道如何做,類似yaml文件的語法,開始准備用word字符替換的,發現有點行不通,結束}不知道該如何替換。

貌似用棧可以解決這個問題,暫時放着。

【答案】

F:分類計數(15分)

【問題描述】

輸入一個字符串,請輸出這個字符串包含多少個大寫字母,多少個小寫字
母,多少個數字。

【輸入格式】

輸入一行包含一個字符串。

【輸出格式】

輸出三行,每行一個整數,分別表示大寫字母、小寫字母和數字的個數。

【樣例輸入】

1+a=Aab

【樣例輸出】

131

【評測用例規模與約定】

對於所有評測用例,字符串由可見字符組成,長度不超過 100。

【解題思路】

這題就是送分題了,只需要三個if就能解決了,判斷出是否是大寫字母,小寫字母,數字,然后計數即可。

【答案】

#include<iostream>
#include<string>
using namespace std;
int main()
{
	string s;
	cin >> s;
	int length = s.size();
	int x=0,y=0,z=0;
	for(int i=0;i<length;i++){
		if('A'<=s[i]&&s[i]<='Z'){
			x++;
		}
		else if('a'<=s[i]&&s[i]<='z'){
			y++;
		}
		else if('0'<=s[i]&&s[i]<='9'){
			z++;
		}
	}
	cout << x << endl;
	cout << y << endl;
	cout << z;
	return 0;
}

G:整除序列(20分)

【問題描述】

有一個序列,序列的第一個數是 n,后面的每個數是前一個數整除 2,請輸
出這個序列中值為正數的項。

【輸入格式】

輸入一行包含一個整數 n。

【輸出格式】

輸出一行,包含多個整數,相鄰的整數之間用一個空格分隔,表示答案。

【樣例輸入】

20

【樣例輸出】

20 10 5 2 1

【評測用例規模與約定】

對於 80% 的評測用例,1 ≤ n ≤ 109。
對於所有評測用例,1 ≤ n ≤ 1018。

【解題思路】

這道題思路也不難,給出一個數,不斷除2,迭代至答案n為0即可。

【答案】

#include<iostream>
#include<string>
using namespace std;
int main()
{
	int n;
	cin >> n;
	while(n>0){
		cout << n << " ";
		n /= 2;
	}
	return 0;
}

H:走方格(20分)

【問題描述】

在平面上有一些二維的點陣。
這些點的編號就像二維數組的編號一樣,從上到下依次為第 1 至第 n 行,
從左到右依次為第 1 至第 m 列,每一個點可以用行號和列號來表示。
現在有個人站在第 1 行第 1 列,要走到第 n 行第 m 列。只能向右或者向下
走。
注意,如果行號和列數都是偶數,不能走入這一格中。
問有多少種方案。

【輸入格式】

輸入一行包含兩個整數 n, m。

【輸出格式】

輸出一個整數,表示答案。

【樣例輸入】

3 4

【樣例輸出】

2

【樣例輸入】

6 6

【樣例輸出】

0

【評測用例規模與約定】

對於所有評測用例,1 ≤ n ≤ 30, 1 ≤ m ≤ 30。

【解題思路】

這題算是圖論里面比較基礎一道題,尋找路徑的種樹,可以用搜索來做,也可以用動態規划。和走台階也類似,,每一個位置都有兩種走法,向右走,向下走,除掉邊界和不可到達的點。

建立一個二維數組,不使用0坐標,從1開始算邊界,二維數組進行循環,當橫縱坐標有一個為1,則說明是邊界,設置為1,當橫縱坐標是偶數時,說明,此點不可達,設為0,其余位置值為左位置和上位置值之和,解決了此問題。

【答案】

#include<iostream>
#include<algorithm>
using namespace std;
int a[35][35];
int main()
{
	for(int i=0;i<35;i++){
		fill(a[i],a[i]+35,0);
	}
	for(int i=0;i<35;i++){
		a[i][1]=1;
		a[1][i]=1;
	}
	int n,m;
	cin >> n >> m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(i==1||j==1){
				a[i][j]=1;
			}
			else if(i%2==0&&j%2==0){
				a[i][j]=0;
			}
			else {
				a[i][j]=a[i-1][j]+a[i][j-1];
			}
		}
	}
	return 0;
}

I:字符串編碼(25分)

【問題描述】

小明發明了一種給由全大寫字母組成的字符串編碼的方法。對於每一個大
寫字母,小明將它轉換成它在 26 個英文字母中序號,即 A → 1, B → 2, … Z →
26。
這樣一個字符串就能被轉化成一個數字序列:
比如 ABCXYZ → 123242526。
現在給定一個轉換后的數字序列,小明想還原出原本的字符串。當然這樣
的還原有可能存在多個符合條件的字符串。小明希望找出其中字典序最大的字
符串。

【輸入格式】

一個數字序列。

【輸出格式】

一個只包含大寫字母的字符串,代表答案

【樣例輸入】

123242526

【樣例輸出】

LCXYZ

【評測用例規模與約定】

對於 20% 的評測用例,輸入的長度不超過 20。
對於所有評測用例,輸入的長度不超過 200000。

【解題思路】

這道題求字典序最大,也就是說,每次還原字符都找字典序最大的字符例如123有三種情況ABC,LC,AW,它們三個字典序最大的就是LC,類似貪心。主要問題每次怎么選到字典序最大的字符。

【答案】

#include<iostream>
#include<string>
using namespace std;
int main()
{
	string s;
	cin >> s;
	int length = s.size();
	for(int i=0;i<length;i++){
		if((i+1)<length&&((s[i]-'0')*10+(s[i+1]-'0'))<=26){
			cout << (char)('A'+((s[i]-'0')*10+(s[i+1]-'0'))-1);
			i++;
		}
		else{
			cout << (char)('A'+(s[i]-'0')-1);
		}
	}
	return 0;
}

J:整數小拼接(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。

【解題思路】

典型的排列問題,直接上八皇后的模板,事實上所有的排列問題,都能用它解決,只需要在排列好兩個數的時候,進行拼接,比較大小,計數即可,唯一害怕的就是時間過不了。

【答案】

#include<iostream>
using namespace std;
int n,k,sum=0;
int a[5];
int b[100005];
bool isok(int r){
	for(int i=0;i<r;i++){
		if(a[i]==a[r]){
			return false;
		}
	}
	return true;
}
void dfs(int r){
	if(r==2){
		int w=1;
		while(b[a[1]]/w){
			w *= 10;
		}
		int cache = b[a[0]]*w+b[a[1]];
		if(cache<k){
			sum++;
		}
		return ;
	}
	for(int i=0;i<4;i++){
		a[r]=i;
		if(isok(r)){
			dfs(r+1);
		}
	}
}
int main()
{
	cin >> n >> k;
	for(int i=0;i<n;i++){
		cin >> b[i];
	}
	dfs(0);
	cout << sum;
	return 0;
}

參考鏈接

第十一屆藍橋杯省賽第一場原題

原文鏈接

https://srcrs.top 是我的個人博客地址,本文源地址:https://srcrs.top/posts/202007061.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM