1. 程式人生 > >(2017)第八屆藍橋杯大賽個人賽省賽(軟體類) C/C++ 大學A組 題解(第五題和第六題)

(2017)第八屆藍橋杯大賽個人賽省賽(軟體類) C/C++ 大學A組 題解(第五題和第六題)

前言

今天是情人節呢❤ 正好現在睡不著,先解決簡單的題吧。

程式碼填空題區

程式碼填空題:要求選手在弄清給定程式碼工作原理的基礎上填寫缺失的部分,使得程式邏輯正確、完整。

把程式碼填空的答案(僅填空處的答案,不包括題面已存在的程式碼或符號)直接通過網頁提交即可,不要書寫多餘的內容。

使用ANSI C/ANSI C++ 標準,不要依賴作業系統或編譯器提供的特殊函式。

這部分的題往往都是最簡單的(所以相對的佔的分值也比較小),這也是我們應該爭取全部做對的。

由於題目會給出主要程式碼,所以你在填寫完缺失的部分後往往可以通過執行改程式碼檢驗其是否正確。

第五題

題目

標題:字母組串
由 A,B,C 這3個字母就可以組成許多串。
比如:"A","AB","ABC","ABA","AACBB" ....
現在,小明正在思考一個問題:
如果每個字母的個數有限定,能組成多少個已知長度的串呢?
他請好朋友來幫忙,很快得到了程式碼,
解決方案超級簡單,然而最重要的部分卻語焉不詳。
請仔細分析原始碼,填寫劃線部分缺少的內容。
#include <stdio.h>
// a個A,b個B,c個C 字母,能組成多少個不同的長度為n的串。
int f(int a, int b, int c, int n)
{
	if(a<0 || b<0 || c<0) return 0;
	if(n==0) return 1; 	
	return ______________________________________ ;  // 填空
}
int main()
{
	printf("%d\n", f(1,1,1,2));
	printf("%d\n", f(1,2,3,3));
	return 0;
}
對於上面的測試資料,小明口算的結果應該是:
6
19

注意:只填寫劃線部分缺少的程式碼,不要提交任何多餘內容或說明性文字。

分析

寫的很短,通過註釋我們可以看出f(a,b,c,n)可以直接求出答案。

那麼我們就需要考慮f(a,b,c,n)是如何計算出來的。

首先,它考慮了a、b、c小於0或者n=0的情況,這是幾種特殊情況,可以直接得到解,那麼剩下的情況就都是無法直接求解的。

那麼我們就需要把它轉換成若干個子問題求解,直到轉換成給出的幾種特殊情況為止。

我們從已知的開始,a、b、c小於0不做考慮,這些表示了非法狀態。

n=0可以得到答案為1,那麼n=1呢?

n=1就相當於在n=0後加了一個字母,那麼也就是說我現在有幾種字母我就有幾種可能性。

那麼對於n=1的情況來說,要想轉換成n=0,我只需要減去abc3種字母中存在的某一種就好了,當然不存在字母也可以這樣考慮,因為程式碼裡已經替我們寫好非法情況了。

一般地,我們可以推出f(a,b,c,n)= f(a-1,b,c,n-1)+f(a,b-1,c,n-1)+f(a,b,c-1,n-1)

那麼語句裡填寫的就應該是f(a-1,b,c,n-1)+f(a,b-1,c,n-1)+f(a,b,c-1,n-1)

你會發現,在函式f中包含了若干個f函式的使用,這種方法被稱之為遞迴。

遞迴由遞迴函式和遞迴出口兩部分組成。題目中給的特殊情況就是這個遞迴的遞迴出口,而我們實現的就是遞迴函式。

程式碼及執行結果

#include <stdio.h>
// a個A,b個B,c個C 字母,能組成多少個不同的長度為n的串。
int f(int a, int b, int c, int n)
{
	if(a<0 || b<0 || c<0) return 0;
	if(n==0) return 1;
	return f(a-1,b,c,n-1)+f(a,b-1,c,n-1)+f(a,b,c-1,n-1);  // 填空
}
int main()
{
	printf("%d\n", f(1,1,1,2));
	printf("%d\n", f(1,2,3,3));
	return 0;
}

第六題

題目

標題:最大公共子串
最大公共子串長度問題就是:
求兩個串的所有子串中能夠匹配上的最大長度是多少。
比如:"abcdkkk" 和 "baabcdadabc",
可以找到的最長的公共子串是"abcd",所以最大公共子串長度為4。
下面的程式是採用矩陣法進行求解的,這對串的規模不大的情況還是比較有效的解法。
請分析該解法的思路,並補全劃線部分缺失的程式碼。

#include <stdio.h>
#include <string.h>
#define N 256
int f(const char* s1, const char* s2)
{
	int a[N][N];
	int len1 = strlen(s1);
	int len2 = strlen(s2);
	int i,j;
	memset(a,0,sizeof(int)*N*N);
	int max = 0;
	for(i=1; i<=len1; i++){
		for(j=1; j<=len2; j++){
			if(s1[i-1]==s2[j-1]) {
				a[i][j] = __________________________;  //填空
				if(a[i][j] > max) max = a[i][j];
			}
		}
	}
	return max;
}
int main()
{
	printf("%d\n", f("abcdkkk", "baabcdadabc"));
	return 0;
}
注意:只提交缺少的程式碼,不要提交已有的程式碼和符號。也不要提交說明性文字。

分析

觀察程式碼,答案是一個叫max的東西,而這個東西代表著一個二維陣列a裡的最大值。

而a[i][j]又會隨著s1[i-1]==s2[j-1]而更新。

那麼a代表什麼才能使max符合答案呢?

s1[i-1]==s2[j-1]代表著第一個字串的第i個字元與第二個字串的第j個字元相同,那麼這個相同的字元就可以構成一個公共子串。

我們就可以考慮到,如果這個字元的前面恰好是一個公共子串的話,公共子串的長度就可以獲得更新,也就是+1。

所以,a[i][j]表示兩個字串的公共子串在第一個字串中最後一個字元是第i個字元,在第二個字串中最後一個字元是第j個字元的那個公共子串的長度。

那麼更新這個長度用程式碼寫出來就是a[i][j] = a[i - 1][j - 1] + 1;

語句裡填寫的就是a[i - 1][j - 1] + 1

程式碼及執行結果

#include <stdio.h>
#include <string.h>
#define N 256
int f(const char* s1, const char* s2)
{
	int a[N][N];
	int len1 = strlen(s1);
	int len2 = strlen(s2);
	int i,j;
	memset(a,0,sizeof(int)*N*N);
	int max = 0;
	for(i=1; i<=len1; i++){
		for(j=1; j<=len2; j++){
			if(s1[i-1]==s2[j-1]) {
				a[i][j] = a[i - 1][j - 1] + 1;  //填空
				if(a[i][j] > max) max = a[i][j];
			}
		}
	}
	return max;
}
int main()
{
	printf("%d\n", f("abcdkkk", "baabcdadabc"));
	return 0;
}

(確實很簡單對吧=w=)

相關推薦

2017藍橋大賽個人賽軟體 C/C++ 大學A 題解

前言今天是情人節呢❤ 正好現在睡不著,先解決簡單的題吧。程式碼填空題區程式碼填空題:要求選手在弄清給定程式碼工作原理的基礎上填寫缺失的部分,使得程式邏輯正確、完整。把程式碼填空的答案(僅填空處的答案,不包括題面已存在的程式碼或符號)直接通過網頁提交即可,不要書寫多餘的內容。使

2017藍橋大賽個人賽軟體 C/C++ 大學A 題解

前言在回北京的火車上,今天就先解決一道簡單的題吧=w=第九題題目標題: 分巧克力兒童節那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友們。小明一共有N塊巧克力,其中第i塊是Hi x Wi的方格組成的長方形。為了公平起見,小明需要從這 N 塊巧克力中切出K塊巧克力

2017藍橋大賽個人賽軟體 C/C++ 大學A 題解

前言完成了回貴州的老家之行,也該回學校啦=w=這次的題目是我個人認為最棘手的一道題,當然從表面上看這道題還是很容易的第八題題目標題:包子湊數小明幾乎每天早晨都會在一家包子鋪吃早餐。他發現這家包子鋪有N種蒸籠,其中第i種蒸籠恰好能放Ai個包子。每種蒸籠都有非常多籠,可以認為是無

2017藍橋大賽個人賽軟體 C/C++ 大學A 題解第一第二

前言正好今天在等面試= =學弟讓我幫忙做一下題解,我就在這裡寫好啦。這也是我的第一篇部落格=w=我覺得我省賽的水平還是沒問題的,第六屆第七屆我都是吉林省第二名,當然省賽的題目本身對演算法的考察度不高。。。很暴力的那種= =這篇題解針對的是對演算法瞭解不深的同學們=w= 所以對

藍橋大賽個人賽軟體B

第八屆藍橋杯大賽個人賽省賽(軟體類)真題標題: 購物單    小明剛剛找到工作,老闆人很好,只是老闆夫人很愛購物。老闆忙的時候經常讓小明幫忙到商場代為購物。小明很厭煩,但又不好推辭。    這不,XX大促銷又來了!老闆夫人開出了長長的購物單,都是有打優惠的。    小明也有個

藍橋大賽個人賽題目答案

第八屆省賽題目 1 題目 標題:迷宮 X星球的一處迷宮遊樂場建在某個小山坡上。 它是由10x10相互連通的小房間組成的。 房間的地板上寫著一個很大的字母。 我們假設玩家是面朝上坡的方向站

藍橋大賽個人賽軟件B

string 問題 pan 圖1 http this 藍橋杯 不同 ogr 3.湊算式 B DEFA + --- + ------- = 10 C GHI (如果顯示有問題,可以參見【圖1.jpg】) 這個算式中A~I代表1~

藍橋大賽個人賽軟體A

方格填數 如下的10個格子 ±-±-±-+ | | | | ±-±-±-±-+ | | | | | ±-±-±-±-+ | | | | ±-±-±-+ (如果顯示有問題,也可以參看【圖1.jpg】) 填入0~9的數字。要求:連續的兩個數字不能相鄰。 (左右、上下、對角都算相鄰) 一共有多少種

藍橋大賽個人賽軟體A第二

生日蠟燭 某君從某年開始每年都舉辦一次生日party,並且每次都要吹熄與年齡相同根數的蠟燭。 現在算起來,他一共吹熄了236根蠟燭。 請問,他從多少歲開始過生日party的? 請填寫他開始過生日party的年齡數。 程式碼: #include <iostream> using

藍橋大賽個人賽軟體A第一

某君新認識一網友。 當問及年齡時,他的網友說: “我的年齡是個2位數,我比兒子大27歲, 如果把我的年齡的兩位數字交換位置,剛好就是我兒子的年齡” 請你計算:網友的年齡一共有多少種可能情況? 程式碼: #include <iostream> using namespa

藍橋大賽個人賽C++ A 題解+原 填空

#include <stdio.h> void swap(int a[], int i, int j) { int t = a[i]; a[i] = a[j]; a[j] = t; } int partition(int a[], int p, int r) { int i = p;

藍橋大賽個人賽軟體 C語言B 3

B組2題和A組的是重複的,so,跳過~ 題目:湊算式      B      DEF A + --- + ------- = 10      C      GHI      (如果顯示有問題,可以參見【圖1.jpg】)    這個算式中A~I代表1~9的數字,不同的字

藍橋大賽個人賽軟體B

本文持續更新,直至更完。 1.網友年齡 某君新認識一網友。 當問及年齡時,他的網友說: “我的年齡是個2位數,我比兒子大27歲, 如果把我的年齡的兩位數字交換位置,剛好就是我兒子的年齡” 請你計算:

藍橋大賽個人賽軟體 C語言B 1

本來想繼續擼a組第三道的,然而一小時還沒弄會。。。so決定改天再弄。先做做b組的。畢竟報的b哈哈。 題目:煤球數目 有一堆煤球,堆成三角稜錐形。具體: 第一層放1個, 第二層3個(排列成三角形),

藍橋大賽個人賽軟體 C語言b (個人解題思路)

1.煤球數目有一堆煤球,堆成三角稜錐形。具體:第一層放1個,第二層3個(排列成三角形),第三層6個(排列成三角形),第四層10個(排列成三角形),....如果一共有100層,共有多少個煤球?請填表示煤球總數目的數字。注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性

藍橋大賽個人賽C++ B 題解+原 填空

1.煤球數目 有一堆煤球,堆成三角稜錐形。具體: 第一層放1個, 第二層3個(排列成三角形), 第三層6個(排列成三角形), 第四層10個(排列成三角形), .... 如果一共有100層,共有多少個煤

藍橋大賽個人賽軟體java語言B---2.生日蠟燭

生日蠟燭某君從某年開始每年都舉辦一次生日party,並且每次都要吹熄與年齡相同根數的蠟燭。現在算起來,他一共吹熄了236根蠟燭。請問,他從多少歲開始過生日party的?請填寫他開始過生日party的年齡

藍橋大賽個人賽C語言A題目答案

第七屆省賽題目 注意 簡單的題目,只是寫了一個函式實現功能,對於複雜的題目,會給出全部程式碼 1 題目 網友年齡 某君新認識一網友。 當問及年齡時,他的網友說: “我的年齡是個2位數,我比兒子大27歲, 如果把我的年齡的兩位數字交換位置

藍橋大賽個人賽決賽軟體 -----Java大學C------樹形顯示

標題:樹形顯示對於分類結構可以用樹形來形象地表示。比如:檔案系統就是典型的例子。樹中的結點具有父子關係。我們在顯示的時候,把子項向右縮排(用空格,不是tab),並新增必要的連線線,以使其層次關係更醒目。下面的程式碼就是為了這個目的的,請仔細閱讀原始碼,並填寫劃線部分缺少的程式

藍橋大賽個人賽決賽軟體 Java大學B 答案

標題:平方十位數由0~9這10個數字不重複、不遺漏,可以組成很多10位數字。這其中也有很多恰好是平方數(是某個數的平方)。比如:1026753849,就是其中最小的一個平方數。請你找出其中最大的一個平方數是多少?注意:你需要提交的是一個10位數字,不要填寫任何多餘內容。答案: