1. 程式人生 > >2016第七屆藍橋杯C/C++ B組省賽題解

2016第七屆藍橋杯C/C++ B組省賽題解

前言:

已經是第二次參加藍翔杯了,又是凌晨四點半天還沒亮就要屁顛屁顛的起來。然後坐著學校大巴車來到成都理工。到了學校提前了2個小時啊。。。瞌睡來忙了沒地方睡。和一幫兄弟帶著三個大一的繞著理工逛了一圈,說實話,學校風景真不乍地。回到考場基本就要到比賽時間了。好了不多說了開始看題吧。

第一題:

煤球數目

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


請填表示煤球總數目的數字。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

這道題坑死了,第一次看堆成三角稜錐形,草稿本畫半天都沒畫出個三角稜錐。後來單獨看每句話才知道每層一個三角形疊起來就是三角稜錐。我去。

看懂題目這個題目就很簡單了,每層的個數是上層的個數加上層數,意思就是An = An-1 + n,然而題目是求的前100層一共多少煤球。所以是Sn.程式碼雙重for迴圈就出來了。答案是:171700

#include<stdio.h>
int main()
{
	int a[101] ={0};
	for(int i = 1 ; i < 101 ; i ++)
		a[i] = a[i-1] + i;
	int ans = 0;
	for(int j = 1 ; j < 101 ; j ++)
		ans += a[j];
	printf("%d\n",ans);
	return 0;
}


第二題:


生日蠟燭

某君從某年開始每年都舉辦一次生日party,並且每次都要吹熄與年齡相同根數的蠟燭。

現在算起來,他一共吹熄了236根蠟燭。

請問,他從多少歲開始過生日party的?

請填寫他開始過生日party的年齡數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

呵呵,水題,但是出題人不嚴謹啊!!!怎麼就不能考慮萬一他今年236歲呢....好了不說了強迫症犯了。

藍橋杯這種不像acm的題目的,能暴力直接暴力。不用想太多。直接從1~236 列舉 start, end 分別表示他開始過生日的年齡和今年的年齡,然後計算之間吹蠟燭的總和如果等於236就輸出start ,end.  答案是:26

#include<stdio.h>
int main()
{
	int start,end;
	for(start = 1 ; start < 236 ; start ++)
	{
		for( end = start ; end < 236 ; end ++ )
		{
			int sum = 0;
			for(int i = start; i <= end; i ++)
				sum += i;
			if( sum == 236)
			{
				printf("start : %d end : %d\n",start,end);
			}
		}
	}
	return 0;
}


第三題:


湊算式

       B      DEF
A + — + -——— = 10
       C       GHI

(如果顯示有問題,可以參見【圖1.jpg】)

這個算式中A~I代表1~9的數字,不同的字母代表不同的數字。

比如:
6+8/3+952/714 就是一種解法,
5+3/1+972/486 是另一種解法。

這個算式一共有多少種解法?

注意:你提交應該是個整數,不要填寫任何多餘的內容或說明性文字。


這個題不多說了,直接暴力生成9的全排列然後去驗證等式是否成立,只是驗證的時候如果防止精度問題可以通分把除法變成乘法。 答案是:29
#include<stdio.h>
int ans = 0;
int num[10];
bool visit[10];

void Solve()
{
	double sum = num[0] + (double)num[1] / num[2] + (double)(num[3]*100+num[4]*10+num[5])/(num[6]*100+num[7]*10+num[8]);
	if(sum == 10)
	{
		ans ++;
	}
}

void dfs(int index)
{
	if(index == 9)
	{
		Solve();
		return ;
	}
	for(int i = 1 ; i < 10 ; i ++)
	{
		if(!visit[i])
		{
			visit[i] = true;
			num[index] = i;
			dfs(index+1);
			visit[i] = false;
		}
	}
}

int main()
{
	dfs(0);
	printf("%d\n",ans);
	return 0;
}


第四題:
快速排序

排序在各種場合經常被用到。
快速排序是十分常用的高效率的演算法。

其思想是:先選一個“標尺”,
用它把整個佇列過一遍篩子,
以保證:其左邊的元素都不大於它,其右邊的元素都不小於它。

這樣,排序問題就被分割為兩個子區間。
再分別對子區間排序就可以了。

下面的程式碼是一種實現,請分析並填寫劃線部分缺少的程式碼。

#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;
int j = r + 1;
int x = a[p];
while(1){
while(i<r && a[++i]<x);
while(a[--j]>x);
if(i>=j) break;
swap(a,i,j);
}
______________________;
return j;
}

void quicksort(int a[], int p, int r)
{
if(p<r){
int q = partition(a,p,r);
quicksort(a,p,q-1);
quicksort(a,q+1,r);
}
}

int main()
{
int i;
int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
int N = 12;

quicksort(a, 0, N-1);

for(i=0; i<N; i++) printf("%d ", a[i]);
printf("\n");

return 0;
}


注意:只填寫缺少的內容,不要書寫任何題面已有程式碼或說明性文字。

這個題目如果接觸過快排,瞭解過快速排序的原理的應該是送分題目,只不過快排單步(就是將一堆數按照某個數作為基準數分成左右兩堆)這個實現方式有幾種程式碼表現。在這裡答案是swap(a,p,j). 第五題: 抽籤

X星球要派出一個5人組成的觀察團前往W星。
其中:
A國最多可以派出4人。
B國最多可以派出2人。
C國最多可以派出2人。
....

那麼最終派往W星的觀察團會有多少種國別的不同組合呢?

下面的程式解決了這個問題。
陣列a[] 中既是每個國家可以派出的最多的名額。
程式執行結果為:
DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
BCFFF
BCEFF
BCDFF
BCDEF
....
(以下省略,總共101行)

#include <stdio.h>
#define N 6
#define M 5
#define BUF 1024

void f(int a[], int k, int m, char b[])
{
int i,j;

if(k==N){ 
b[M] = 0;
if(m==0) printf("%s\n",b);
return;
}
for(i=0; i<=a[k]; i++){
for(j=0; j<i; j++) b[M-m+j] = k+'A';
______________________; //填空位置
}
}
int main()
{
int a[N] = {4,2,2,1,1,3};
char b[BUF];
f(a,0,M,b);
return 0;
}

仔細閱讀程式碼,填寫劃線部分缺少的內容。

注意:不要填寫任何已有內容或說明性文字。

這個題目是這樣的,對於f(int a[],int k,int m,char b[]).a[] 是每個國家的最多指派人數,k表示當前是哪個國家,m表示還需要派送幾個人(可以為負數).b表示已經派送的人的字串。 所以這個題目在遞迴中間的的 第一個迴圈表示從0~a[i]中讓i國選擇指派人數,內迴圈只是向b[]記錄的過程。 所以答案是f(a,k+1,m-i,b).     因為這裡I = j .應該 f(a,k+1,m-j,b)也可以。 第六題:

方格填數

如下的10個格子

(如果顯示有問題,也可以參看【圖1.jpg】)

填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)

一共有多少種可能的填數方案?

請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。


這個題目題目有點表述不明,不知道0~9 可不可以重複使用。我當時做的時候是當作不可以重複使用來處理的。那麼這裡我就先當作不可重複使用來講解。 這裡題目還是一樣先往裡面填數。用生成排列的形式。填寫完了之後再判斷是否可行。答案是:1580
#include <stdio.h>
#include <math.h>
int flag[3][4]; //表示哪些可以填數
int mpt[3][4]; //填數
bool visit[10];
int ans = 0;
void init()   //初始化
{
	int i,j;
	for(i = 0 ; i < 3 ; i ++)
		for(j = 0 ; j < 4 ; j ++)
			flag[i][j] = 1;
	flag[0][0] = 0;
	flag[2][3] = 0;
}

void Solve()
{
	int dir[8][2] = { 0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1};
	int book = true;
	for(int i = 0 ; i < 3 ; i ++)
	{
		for(int j = 0 ; j < 4; j ++)
		{
			//判斷每個數週圍是否滿足
			if(flag[i][j] == 0)continue;
			for( int k = 0 ; k < 8 ; k ++)
			{
				int x,y;
				x = i + dir[k][0];
				y = j + dir[k][1];
				if(x < 0 || x >= 3 || y < 0 || y >= 4 || flag[x][y] == 0) continue;
				if(abs(mpt[x][y] - mpt[i][j]) == 1)  book = false;
			}
		}
	}
	if(book) ans ++;
}


void dfs(int index)
{
	int x,y;
	x = index / 4;
	y = index % 4;
	if( x == 3)
	{
		Solve();
		return;
	}
	if(flag[x][y])
	{
		for(int i = 0 ; i < 10 ; i ++)
		{
			if(!visit[i])
			{
				visit[i] = true;
				mpt[x][y] = i;
				dfs(index+1);
				visit[i] = false;
			}
		}
	}
	else
	{
		dfs(index+1);
	}
}
int main()
{
	init();
	dfs(0);
	printf("%d\n",ans);
	return 0;
}


第七題:


剪郵票

如【圖1.jpg】, 有12張連在一起的12生肖的郵票。
現在你要從中剪下5張來,要求必須是連著的。
(僅僅連線一個角不算相連)
比如,【圖2.jpg】,【圖3.jpg】中,粉紅色所示部分就是合格的剪取。

請你計算,一共有多少種不同的剪取方法。

請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。



其實這個題目還是可前面的一樣,先生成,再判斷是否可行。這裡我們可以先用搜索從12個數裡面將所有5個數的組合找出來。然後再用深搜判斷這五個是否連在一起。答案是:116
#include <stdio.h>
#include <string.h>
int mpt[3][4];
int mpt_visit[3][4];
int num[6]; 
int have[13];
int visit[13];
int ans = 0;
int Count = 0;

void init()
{
	int k = 1;
	for(int i = 0 ; i < 3 ; i ++)
		for(int j = 0 ; j < 4 ; j ++)
		{
			mpt[i][j] = k;
			k ++;
		}
}
int dir[4][2] = {0,1,0,-1,-1,0,1,0};
//判斷五個數是否能連在一起
void dfs_find(int x,int y)
{
	for(int i = 0 ; i < 4 ; i++)
	{
		int tx,ty;
		tx = x + dir[i][0];
		ty = y + dir[i][1];
		if(tx < 0 || tx >= 3 || ty < 0 || ty >= 4) continue;
		if(have[mpt[tx][ty]] == 0 || mpt_visit[tx][ty])continue;
		mpt_visit[tx][ty] = 1;
		Count ++;
		dfs_find(tx,ty);
	}
}

void Solve()
{
	int i;
	memset(have,0,sizeof(have));
	memset(mpt_visit,0,sizeof(mpt_visit));
	for(i = 1; i < 6 ; i ++) have[num[i]] = 1;
	for(i = 0 ; i < 12 ; i ++)
	{
		int x,y;
		x = i / 4;
		y = i % 4;
		if(have[mpt[x][y]])
		{
			Count = 1;
			mpt_visit[x][y] =1;
			dfs_find(x,y);
			break;
		}
	}
	if(Count == 5)
	{
		ans ++;
	}
}

//建立5個數的組合
void dfs_creat(int index)
{
	if(index == 6)
	{
		Solve();
		return;
	}
	for(int i = num[index-1] + 1; i < 13 ; i ++)
	{
		if(!visit[i])
		{
			visit[i] = true;
			num[index] = i;
			dfs_creat(index+1);
			visit[i] = false;
		}
	}
}

int main()
{
	init();
	dfs_creat(1);
	printf("%d\n",ans);
	return 0;
}


第八題:


四平方和

四平方和定理,又稱為拉格朗日定理:
每個正整數都可以表示為至多4個正整數的平方和。
如果把0包括進去,就正好可以表示為4個數的平方和。

比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符號表示乘方的意思)

對於一個給定的正整數,可能存在多種平方和的表示法。
要求你對4個數排序:
0 <= a <= b <= c <= d
並對所有的可能表示法按 a,b,c,d 為聯合主鍵升序排列,最後輸出第一個表示法

程式輸入為一個正整數N (N<5000000)
要求輸出4個非負整數,按從小到大排序,中間用空格分開

相關推薦

2016藍橋大賽C

第一題 報紙頁數 X星球日報和我們地球的城市早報是一樣的, 都是一些單獨的紙張疊在一起而已。每張紙印有4版。 比如,某張報紙包含的4頁是:5,6,11,12, 可以確定它應該是最上邊的第2張報紙。 我們在太空中撿到了一張X星球的報紙,4個頁碼分別是:

藍橋Java語言B真題()

今天參加藍橋JAVA語言B組的競賽剛剛結束,把真題和大家分享一下。 1.煤球數目  (結果填空) 有一堆煤球,堆成三角稜錐形。具體: 第一層放1個, 第二層3個(排列成三角形), 第三層6個(排列成三角形), 第四層10個(排列成三角形), .... 如果一共有100

2016藍橋決賽c/c++本科B試題總結及解題答案

未完待更新........ 1.一步之遙 從昏迷中醒來,小明發現自己被關在X星球的廢礦車裡。 礦車停在平直的廢棄的軌道上。 他的面前是兩個按鈕,分別寫著“F”和“B”。 小明突然記起來,這

2016藍橋C/C++ B題解 H題

四平方和 四平方和定理,又稱為拉格朗日定理: 每個正整數都可以表示為至多4個正整數的平方和。 如果把0包括進去,就正好可以表示為4個數的平方和。 比如: 5 = 0^2 + 0^2 + 1^2 + 2

2016藍橋C試題及部分答案

答案都是自己理解的 1.報紙頁數 X星球日報和我們地球的城市早報是一樣的,都是一些單獨的紙張疊在一起而已。每張紙印有4版。比如,某張報紙包含的4頁是:5,6,11,12,可以確定它應該是最上邊的第2張報紙。我們在太空中撿到了一張X星球的報紙,4個頁碼分別是: 1125,11

2016藍橋C/C++ B題解

前言: 已經是第二次參加藍翔杯了,又是凌晨四點半天還沒亮就要屁顛屁顛的起來。然後坐著學校大巴車來到成都理工。到了學校提前了2個小時啊。。。瞌睡來忙了沒地方睡。和一幫兄弟帶著三個大一的繞著理工逛了一圈,說實話,學校風景真不乍地。回到考場基本就要到比賽時間了。好了不多說了開始

2016藍橋c/c++本科B試題總結及解題答案

第一題:煤球數目第i層的煤球陣列為(1+n)*n/2,答案:171700第二題:生日蠟燭思路:1 2 3 4 5 6……這一個等差數列的前n項和為(1+n)*n/2設從a歲開始過生日,到了b歲一共吹熄了236根蠟燭。即為:(a+b)(b-a+1)/2=236,答案:26for

2016藍橋C/C++ B第二題:生日蠟燭

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

2016藍橋C/C++ B五題:抽籤

/*抽籤 X星球要派出一個5人組成的觀察團前往W星。 其中: A國最多可以派出4人。 B國最多可以派出2人。 C國最多可以派出2人。 .... 那麼最終派往W星的觀察團會有多少種國別的不同組合呢? 下面的程式解決了這個問題。 陣列a[] 中既是每個國家可以派出的最多的名額。

2016藍橋C++B八題:四平方和

題目: 四平方和 四平方和定理,又稱為拉格朗日定理: 每個正整數都可以表示為至多4個正整數的平方和。 如果把0包括進去,就正好可以表示為4個數的平方和。 比如: 5 = 0^2 + 0^2

2016藍橋C/C++ B第一題:煤球數目

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

藍橋Java C決賽試題

1.平方末尾能夠表示為某個整數的平方的數字稱為“平方數”比如,25,64雖然無法立即說出某個數是平方數,但經常可以斷定某個數不是平方數。因為平方數的末位只可能是:[0, 1, 4, 5, 6, 9] 這6個數字中的某個。所以,4325435332必然不是平方數。如果給你一個2

2015藍橋決賽C語言A--穿越雷區(DFS)

X星的坦克戰車很奇怪,它必須交替地穿越正能量輻射區和負能量輻射區才能保持正常運轉,否則將報廢。 某坦克需要從A區到B區去(A,B區本身是安全區,沒有正能量或負能量特徵),怎樣走才能路徑最短? 已知的地

藍橋大學生Cjava決賽題目 密文搜尋

標題:密文搜尋福爾摩斯從X星收到一份資料,全部是小寫字母組成。他的助手提供了另一份資料:許多長度為8的密碼列表。福爾摩斯發現,這些密碼是被打亂後隱藏在先前那份資料中的。請你編寫一個程式,從第一份資料中搜

2016藍橋-大學A 隨意組合(dfs)

描述 小明被綁架到X星球的巫師W那裡。 其時,W正在玩弄兩組資料 (2 3 5 8) 和 (1 4 6 7) 他命令小明從一組資料中分別取數與另一組中的數配對,共配成4對(組中的

藍橋2015本科Bc/++部分解題報告

今天是2015年4月11日,昨天剛從hz趕回來,好久不寫程式碼,手感有些生疏,~~ 一、獎券數目(3分) 有些人很迷信數字,比如帶“4”的數字,認為和“死”諧音,就覺得不吉利。 雖然這些說法純屬無稽之談,但有時還要迎合大眾的需求。某抽獎活動的獎券號碼是5位數(10000-9

2016藍橋-四平方和(理論不超時)

四平方和 四平方和定理,又稱為拉格朗日定理: 每個正整數都可以表示為至多4個正整數的平方和。 如果把0包括進去,就正好可以表示為4個數的平方和。 比如: 5 = 0^2 + 0^2 + 1^2 + 2^2 7 = 1^2 + 1^2 + 1^2 +

2016 藍橋 全國總決賽B題(完全平方數)

題目意思就是: 給你0,1,2,3,4,5,6,7,8,9十個數字,要你選出任意一個或幾個組合在一起成為完全平方數,每個數字都必須選且只能選一次,求可能的方案。 比如有其中幾種符合題意的情況: 0 16 25 73984 0 1 625 73984 0

2016藍橋 02 生日蠟燭(java)

生日蠟燭某君從某年開始每年都舉辦一次生日party,並且每次都要吹熄與年齡相同根數的蠟燭。現在算起來,他一共吹熄了236根蠟燭。請問,他從多少歲開始過生日party的?請填寫他開始過生日party的年齡數。注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。答案

2017藍橋決賽(B)2.磁磚樣式

利用 分享 部分 span 裝飾 mage 整數 bool png 磁磚樣式 小明家的一面裝飾墻原來是 310 的小方格。 現在手頭有一批剛好能蓋住2個小方格的長方形瓷磚。 瓷磚只有兩種顏色:黃色和橙色。 小明想知道,對於這麽簡陋的原料,可以貼出多少種不同的花樣來。 小明有