第十一屆藍橋杯B組省賽第二場


這屆是我第一次參加藍橋杯,只拿了個省三,說實話,我的很多水平沒發揮出來,看到結果后我也特別難受,我甚至懷疑自己是不是白訓練了,找了很多算法大佬談話。。還是做得題太少了吧,
再加上個人特別要強,所以對這個結果難以接受。我在此決定強迫自己每天都寫一篇博客,每天都練習算法,一定要在來年三月挺進國賽!!!
毫不掩飾,我比賽的時候 C、D、E、F題都錯了 , F題把我看懵逼了,好簡單呀。。我用了強制類型轉換,結果出來負數,我看了半天都搞不懂哪里錯了,我覺得自己很對,然后就交了,實際上大佬
跟我說強制類型轉換容易出各種小問題,也算是長知識了吧。 C、D兩題是真的就錯的挺離譜的 , 原因是第一自己打代碼還是不夠穩,第二還是自己太粗心,以后會加以改正!
會繼續努力,繼續揚帆起航,不為一次比賽而放棄追夢的路!
下面來復盤一下比賽:

試題A 門牌制作
【問題描述】
小藍要為一條街的住戶制作門牌號。
這條街一共有 2020 位住戶,門牌號從 1 到 2020 編號。
小藍制作門牌的方法是先制作 0 到 9 這幾個數字字符,最后根據需要將字
符粘貼到門牌上,例如門牌 1017 需要依次粘貼字符 1、0、1、7,即需要 1 個
字符 0,2 個字符 1,1 個字符 7。
請問要制作所有的 1 到 2020 號門牌,總共需要多少個字符 2?
【答案提交】
這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一
個整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
題解:
答案:624

//這是一道簡單題,遍歷一下看每一位數是不是2即可。
#include<iostream>

using namespace std;

int res ;

int main(){
	for(int i = 1 ; i <= 2020 ; i ++){
		int j = i;
		while(j){
			if(j % 10 == 2) res ++;
			j /= 10;
		}
	}
	cout << res;
	return 0;
}

B 既約分數
【問題描述】
如果一個分數的分子和分母的最大公約數是 1,這個分數稱為既約分數。
例如,34 , 52 , 18 , 71 都是既約分數。
請問,有多少個既約分數,分子和分母都是 1 到 2020 之間的整數(包括 1 和 2020)?
【答案提交】
這是一道結果填空題,你只需要算出結果后提交即可。本題的結果為一個
整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
題解:
答案:2481215

//求最大公約數問題
#include<bits/stdc++.h>

using namespace std;

long long res;

int gcd(int x , int y){
	int ans;
	if(x < y) swap(x , y);
	while(1){
		int t = x % y;
		x = y;
		y = t;
		if(t == 0) break;
	} 
	return x;
}
int main(){
	for(int i = 1; i <= 2020 ; i ++){
		for(int j = 1 ; j <= 2020 ; j ++){
			if(gcd(i , j) == 1) res ++;
		}
	}
	cout << res ;
	return 0;
}

試題 C: 蛇形填數
【問題描述】
如下圖所示,小明用從 1 開始的正整數“蛇形”填充無限大的矩陣。
1 2 6 7 15 ...
3 5 8 14 ...
4 9 13 ...
10 12 ...
11 ...
...
容易看出矩陣第二行第二列中的數是 5。請你計算矩陣中第 20 行第 20 列
的數是多少?
【答案提交】
這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一
個整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
題解:
答案:761
比賽的時候整個人都傻了,沒發現規律,還是經驗不足。。
賽后重新看了一下這個題,發現還是很簡單的(此時想打自己。。)
首先每個對角線上的數字總數是以等差為1,首項為1遞增的等差數列。
其次可以觀察推導出,每個(x,x)列的數都在第(2*x - 1)個對角線上,且該對角線的元素個數為奇數個,即我們所求元素為對角線上所有數的平均數。
所以(20,20)列對應的數在第39個對角線上。 通過等差數列前n項和計算公式得前38對角線元素個數為741,前39對角線個數為780
所以可以得知: 第39對角線的元素是從742到780之間的數,求他們的平均值即可。

#include<bits/stdc++.h>

using namespace std;

long long sum;
int main(){
	for(int i = 742 ; i <= 780 ; i ++){
		sum += i;
	}
	sum /= 39;
	cout << sum;
	
	return 0;
} 

試題 D: 跑步鍛煉
【問題描述】
小藍每天都鍛煉身體。
正常情況下,小藍每天跑 1 千米。如果某天是周一或者月初(1 日),為了
激勵自己,小藍要跑 2 千米。如果同時是周一或月初,小藍也是跑 2 千米。
小藍跑步已經堅持了很長時間,從 2000 年 1 月 1 日周六(含)到 2020 年
10 月 1 日周四(含)。請問這段時間小藍總共跑步多少千米?
【答案提交】
這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一
個整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
題解:8879
說實話,這道題本人做的時候比起多數人用Excel和查表,本人寫的代碼做的,但是我忽略了閏年這個操作(我都想扇自己QwQ)
這道題,就注意一些情況的考慮就行了,沒什么難度。

//D 跑步鍛煉 
#include<bits/stdc++.h>

using namespace std;

int res , week = 6;

int flag ;

int mon[13] = {-1 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31};

int main(){
	int y , m , d;
	cin >> y >> m >> d;
	for(int i = 2000 ; i <= y ; i ++){
		for(int j = 1 ; j <= 12 ; j ++){
			int sum = mon[j];
			if(((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) && (j == 2)) sum ++;
			for(int k = 1 ; k <= sum ; k ++){
				res ++;
				if(k == 1 || week == 1) res ++;
				if(++ week == 8) week = 1;
				if(i == y && j == m && k == d){
					flag = 1;
					break;
				} 
			}
			if(flag) break;
		}
	}
	cout << res;
	return 0;
}

試題 E: 七段碼

【問題描述】
小藍要用七段碼數碼管來表示一種特殊的文字。
上圖給出了七段碼數碼管的一個圖示,數碼管中一共有 7 段可以發光的二
極管,分別標記為 a, b, c, d, e, f, g。
小藍要選擇一部分二極管(至少要有一個)發光來表達字符。在設計字符
的表達時,要求所有發光的二極管是連成一片的。
例如:b 發光,其他二極管不發光可以用來表達一種字符。
例如:c 發光,其他二極管不發光可以用來表達一種字符。這種方案與上
一行的方案可以用來表示不同的字符,盡管看上去比較相似。
例如:a, b, c, d, e 發光,f, g 不發光可以用來表達一種字符。
例如:b, f 發光,其他二極管不發光則不能用來表達一種字符,因為發光
的二極管沒有連成一片。
請問,小藍可以用七段碼數碼管表達多少種不同的字符?
【答案提交】
這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一
個整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
題解:
答案:80
這道題比賽的時候本人是真的沒想到dfs來做,還是做得題太少了。。得更努力。
這道題是dfs的應用,關鍵點在於尋找不重復的路徑,在此運用了set集合這個內部用紅黑樹實現的STL庫。

#include<bits/stdc++.h>

using namespace std;
//用於字符排序 
char r[8];
//用於存儲總的路徑數 
int ans;
//用於表示當前點的狀態 
int st[3][3];
//用於描述點的值 
char a[3][3]={{'a','b','\0'},{'f','g','c'},{'\0','e','d'}};
//用於上下左右移動 
int dx[] = {-1 , 1 , 0 , 0};
int dy[] = {0 , 0 , -1 , 1};

//用於去重 
set<string> t;

//用於刪除空格,並將字符排序 
void deletespace(string ss){
	for(int i = 0 ; i < 8 ; i ++){
		r[i] = '\0';
	}
	int m = 0 ;
	for(int i = 0 ; i < ss.size() ; i ++){
		if(ss[i] != '\0')
			r[m ++] = ss[i];
	}
	sort(r , r + m);
}
//用於搜索全部路徑
//x,y用於存放當前點的坐標
//ss用於記錄當前路徑 
void dfs(int x,int y,string ss){
	st[x][y] = 1;
	for(int i = 0 ; i < 4 ; i ++){
		int xx = x + dx[i];
		int yy = y + dy[i];
		if(xx >= 0 && xx <= 2 && yy >= 0 && yy <= 2 && !st[xx][yy]){
			ans ++;
			
			deletespace(ss + a[xx][yy]);
			t.insert(r);
			dfs(xx , yy , r);
		}
	}
	st[x][y] = 0;
}
int main(){
	//整體思路講解
	//1.從每個點都要出發一次
	//2.ans表示路徑數 ss表示當前路徑字符串 
	//3.deletespace可以刪除當前路徑字符串中的'\0',同時將字符串內部從小到大排序,存儲在char r[8];中 
	//4.將處理完后的字符串保存到集合中,因為集合具有自動去重功能 
	//5.輸出集合大小,即為路徑總數 
	for(int i = 0 ; i < 3 ; i ++){
		for(int j = 0 ; j < 3 ; j ++){
			if(a[i][j] != '\0'){
			ans ++;
			string ss = "";
			ss += a[i][j];
			deletespace(ss);
			t.insert(r);
			dfs(i , j , r);
		}
	}
}
	cout<<"總路徑數:"<<t.size()<<endl;
	cout << "所有路徑如下:"  << endl;
	for(set<string>::iterator it = t.begin() ; it != t.end() ; it ++) cout << *it << endl;
	
	return 0;
} 

到此填空題就完了hhh


免責聲明!

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



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