第十一屆藍橋杯省內模擬賽部分題解

一、字母排列
  將LANQIAO中的字母重新排列,可以得到不同的單詞,如LANQIAO、AAILNOQ等,注意這7個字母都要被用上,單詞不一定有具體的英文意義。請問,總共能排列如多少個不同的單詞?
答案提交
這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一個整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
題解
這題意圖很明顯,就是考察全排列函數permutation()。代碼如下:

#include <bits/stdc++.h>
using namespace std;
char s[105];
int main(){
	int cnt=0;
    gets(s);
    int n=strlen(s)-1;
	do{
		cnt++;
	}while(next_permutation(s,s+n));
	cout<<cnt;
	return 0;
}

答案爲2520
Tips:全排列函數permutation()所排列的結果會自動屏蔽重複的排列內容,檢驗代碼如下:

#include <bits/stdc++.h>
using namespace std;

int main(){
	int cnt=0;
    int s[]={1,1,1,3};
	do{
		cnt++;
		cout<<s[0]<<s[1]<<s[2]<<s[3]<<endl;
	}while(next_permutation(s,s+4));
	cout<<cnt;
	return 0;
}

二、字節
在計算機存儲中,12.5MB是多少字節?
答案提交
這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一個整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
題解
1MB=2^10 =1024KB
1KB=2^10=1024Byte(字節)
12.5 *1024 *1024=13107200
答案爲13107200

三、括號序列
由1對括號,可以組成一種合法括號序列:()。
由2對括號,可以組成兩種合法括號序列:()()、(())。
由4對括號組成的合法括號序列一共有多少種?
答案提交
這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一個整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
題解:
仔細分類枚舉即可得答案
深度爲1的序列有1種:()()()();
深度爲2的有7種:(())()()、()(())()、()()(())、(()()())、(()())()、()(()())、(())(());
深度爲3的有5種:((()))()、()((()))、((())())、(()(()))、((()()));
深度爲4的有1種:(((())))。
答案爲14

四、無向連通圖
一個包含有2019個結點的無向連通圖,最少包含多少條邊?
答案提交
這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一個整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
題解:
概念複習:在一個無向圖 G 中,若從頂點i到頂點j有路徑相連(當然從j到i也一定有路徑),則稱i和j是連通的。
如果 G 是有向圖,那麼連接i和j的路徑中所有的邊都必須同向。
如果圖中任意兩點都是連通的,那麼圖被稱作連通圖。如果此圖是有向圖,則稱爲強連通圖(注意:需要雙向都有路徑)。
有n個頂點的強連通圖最多有n(n-1)條邊,最少有n條邊。
n個定點的無向連通圖最少有n-1條邊,
n個定點的有向連通圖最少有n條邊,
所以2019個節點的無向連通圖有2019-1=2018條邊。
答案爲2018

五、反倍數
給定三個整數 a, b, c,如果一個整數既不是 a 的整數倍也不是 b 的整數倍還不是 c 的整數倍,則這個數稱爲反倍數。
請問在 1 至 n 中有多少個反倍數?
輸入格式
  輸入的第一行包含一個整數 n。
  第二行包含三個整數 a, b, c,相鄰兩個數之間用一個空格分隔。
輸出格式
  輸出一行包含一個整數,表示答案。
樣例輸入
30
2 3 6
樣例輸出
10
樣例說明
  以下這些數滿足要求:1, 5, 7, 11, 13, 17, 19, 23, 25, 29。
評測用例規模與約定
  對於 40% 的評測用例,1 <= n <= 10000。
  對於 80% 的評測用例,1 <= n <= 100000。
  對於所有評測用例,1 <= n <= 1000000,1 <= a <= n,1 <= b <= n,1 <= c <= n
題解:
這題可以說是入門題,if條件判斷一下就好了。。代碼如下:

#include <bits/stdc++.h>
using namespace std;

int main(){
	long long n,ans=0;
	cin>>n;
	long long a,b,c;
	cin>>a>>b>>c;
	for(long long i=1;i<=n;i++){
		if(i%a&&i%b&&i%c){
			ans++;
		}
	}
	cout<<ans;
	return 0;
}

六、凱撒密碼
定義一個單詞,請使用凱撒密碼將這個單詞加密。
凱撒密碼是一種替換加密的技術,單詞中的所有字母都在字母表上向後偏移3位後被替換成密文。即a變爲d,
b變爲e,…,w變爲z,x變爲a,y變爲b,z變爲c。例如,lanqiao會變成odqtldr。
輸入格式
  輸入一行,包含一個單詞,單詞中只包含小寫英文字母。
輸出格式
  輸出一行,表示加密後的密文。
樣例輸入
lanqiao
樣例輸出
odqtldr
評測用例規模與約定
  對於所有評測用例,單詞中的字母個數不超過100。
題解:
這題依舊很簡單,對於一般字母直接+3,特殊的x,y,z分開來討論即可,但要注意的是x,y,z和一般字母只能分兩類,在分類前提下可以二次分類,不然邏輯上會出錯。。。代碼如下:

#include <bits/stdc++.h>
using namespace std;

int main(){
	char s[105];
	cin>>s;
	for(int i=0;i<strlen(s);i++){
		if(s[i]=='x'||s[i]=='y'||s[i]=='z'){
			if(s[i]=='x'){
				s[i]='a';
			}
			if(s[i]=='y'){
				s[i]='b';
			}
			if(s[i]=='z'){
				s[i]='c';
			}
		}else{
			s[i]+=3;
		}
	}
	puts(s);
	return 0;
}

這裏還有一個網上大神的全能版,他的思路是將字符串轉爲ascall碼,代碼如下:

#include <bits/stdc++.h>
using namespace std;
char s(char ch){
	if(int(ch)>=97&&int(ch)<=127){//小寫字母時,97-122。 
		return char(97+((int(ch)-97+3)%26));
	/*else if(int(ch)>=65&&int(ch)<=90){//大寫字母時,65-90。
		return char(65+((int(ch)-97+3)%26)); 
	*/
	}else{
		//非字母直接返回 
		return ch;
	}
}
int main(){
	string str;
	getline(cin,str);
	for(int i=0;i<str.length();i++){
		str[i]=s(str[i]);
	}
	cout<<str;
	return 0;
}

Tips:cin>>s;與getline(cin,s);的區別:cin>>s;會忽略前面輸入的空格,而getline(cin,s);不會。。。

七、螺旋矩陣
對於一個 n 行 m 列的表格,我們可以使用螺旋的方式給表格依次填上正整數,我們稱填好的表格爲一個螺旋矩陣。
例如,一個 4 行 5 列的螺旋矩陣如下:
1 2 3 4 5
14 15 16 17 6
13 20 19 18 7
12 11 10 9 8
輸入格式
  輸入的第一行包含兩個整數 n, m,分別表示螺旋矩陣的行數和列數。
  第二行包含兩個整數 r, c,表示要求的行號和列號。
輸出格式
  輸出一個整數,表示螺旋矩陣中第 r 行第 c 列的元素的值。
樣例輸入
4 5
2 2
樣例輸出
15
評測用例規模與約定
對於 30% 的評測用例,2 <= n, m <= 20。
對於 70% 的評測用例,2 <= n, m <= 100。
對於所有評測用例,2 <= n, m <= 1000,1 <= r <= n,1 <= c <= m。
題解:
這題其實主要考驗的還是模擬能力,有點類似於走迷宮,採用多個while()循環來模擬還是很好理解的。

#include<bits/stdc++.h>
using namespace std;
int arr[1010][1010];//空間稍微留大一點
int main(){
	int m,n;
	int r,c;
	cin>>m>>n;
	cin>>r>>c;
	int sum=m*n;
	int row=1,col=1,ans=1;
	arr[row][col]=1;
	while(ans<sum){
		while(col+1<=n&&!arr[row][col+1]){// 向右走,直到走到頭或者下一個已經走過
			arr[row][++col]=++ans;
		}
		while(row+1<=m&&!arr[row+1][col]){// 向下走,直到走到頭或者下一個已經走
			arr[++row][col]=++ans;
		}
		while(col-1>=1&&!arr[row][col-1]){ // 向左走,直到走到頭或者下一個已經走過
			arr[row][--col]=++ans;
		}
		while(row-1>=1&&!arr[row-1][col]){// 向上走,直到走到頭或者下一個已經走過
			arr[--row][col]=++ans;
		}
	}
	cout<<arr[r][c];
	return 0;
}

Tips:這裏對數組arr[]初始化時採用全局變量的定義,因爲測試數據達到1000,如果爲局部變量下用memset()來初始化,則會造成溢出。

總結:這次的藍橋杯省內模擬和上次的校內模擬難度總體上差不多,最後三題依舊是有難度的。第八題涉及記憶化搜索,狀態轉移方程還是比較難的;第九題涉及最小生成樹,這個我還沒學好;至於最後一題,畢竟壓軸的,這裏就不多討論了。。總之,通過合理的訓練拿下前七題還是綽綽有餘的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章