2020年第十一屆藍橋杯模擬賽解題報告

@[TOC]文章目錄
填空
1、單位換算
2、約數
3、多少個數字9
4、葉節點個數
代碼
1、數位遞增的數
2、元音輔音元音輔音
3、遞增三元組的中心
4、種草問題
5、奇怪的數列
6、晚會節目

1、單位換算

【問題描述】
在計算機存儲中,15.125GB是多少MB?
【答案提交】
這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一個整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
【解題思路】答案:15488
1GB=1024MB
15.125×1024=15488

2、約數

【問題描述】
1200000有多少個約數(只計算正約數)。
【答案提交】
這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一個整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
【解題思路】答案:96
直接暴力:

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

3、多少個數字9

【問題描述】
在1至2019中,有多少個數的數位中包含數字9?
注意,有的數中的數位中包含多個9,這個數只算一次。例如,1999這個數包含數字9,在計算只是算一個數。
【答案提交】
這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一個整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
【解題思路】答案:544
也是直接暴力一個一個數去判斷:

#include<stdio.h>
int main()
{
	int i,j,k,m,n;
	int sum=0;
	for(i=1;i<=2019;i++)
	{
		m=i;
		while(m!=0)
		{
			n=m%10;
			if(n==9)
			{
				sum++;
				break;
			}
			m=m/10;
		}
	}
	printf("%d\n",sum);
	return 0;
}

4、葉結點的個數

【問題描述】
一棵包含有2019個結點的二叉樹,最多包含多少個葉結點?
【答案提交】
這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一個整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。
【解題思路】答案:2018
這個題有點數據結構的關係,當時用到兩個公式,n0=n2-1,總結點數=n0+n1+n2,並且n1要麼爲0要麼爲1,所以可以求出n0=2018;

1、數位遞增的數

【問題描述】
一個正整數如果任何一個數位不大於右邊相鄰的數位,則稱爲一個數位遞增的數,例如1135是一個數位遞增的數,而1024不是一個數位遞增的數。
給定正整數 n,請問在整數 1 至 n 中有多少個數位遞增的數?
【輸入格式】
輸入的第一行包含一個整數 n。
【輸出格式】
輸出一行包含一個整數,表示答案。
【樣例輸入】
30
【樣例輸出】
26
【評測用例規模與約定】
對於 40% 的評測用例,1 <= n <= 1000。
對於 80% 的評測用例,1 <= n <= 100000。
對於所有評測用例,1 <= n <= 1000000。
【解題思路】這個題數據不大,直接暴力,先把數分散存入數組裏面,然後前後判斷後面的數是否大於前面的數

#include<stdio.h>
#include<string.h>
int main()
{
	int i,j,k,m,n,t,sum,flag;
	int a[100000];
	scanf("%d",&n);
	sum=0;
	if(n<10)//小於10的可以直接判斷
		sum=n;
	else
		sum=9;
	for(i=10;i<=n;i++)
	{
			m=i;k=1;
			while(m!=0)
			{
				t=m%10;
				a[k++]=t;
				m=m/10;
			}
			k--;
			flag=0;
			for(j=1;j<=k;j++)
			{
				if(a[j]<a[j+1])
				{
					flag=1;
					break;
				}
			}
			if(flag==0)
				sum++;
	}
	printf("%d\n",sum);
	return 0;
}

2、元音輔音元音輔音
【問題描述】
小明對類似於 hello 這種單詞非常感興趣,這種單詞可以正好分爲四段,第一段由一個或多個輔音字母組成,第二段由一個或多個元音字母組成,第三段由一個或多個輔音字母組成,第四段由一個或多個元音字母組成。
給定一個單詞,請判斷這個單詞是否也是這種單詞,如果是請輸出yes,否則請輸出no。
元音字母包括 a, e, i, o, u,共五個,其他均爲輔音字母。
【輸入格式】
輸入一行,包含一個單詞,單詞中只包含小寫英文字母。
【輸出格式】
輸出答案,或者爲yes,或者爲no。
【樣例輸入】
lanqiao
【樣例輸出】
yes
【樣例輸入】
world
【樣例輸出】
no
【評測用例規模與約定】
對於所有評測用例,單詞中的字母個數不超過100。

【解題思路】這個題是組成的單詞正好分四段,所以只要判斷元音的連續字段爲2就行了

#include<stdio.h>
#include<string.h>
int main()
{
	char s[105];
	int i,j,k,m,n,flag;
	int sum;
	while(scanf("%s",s)!=EOF)
	{
		n=strlen(s);
		sum=0;
		if(s[0]=='a'||s[0]=='e'||s[0]=='i'||s[0]=='o'||s[0]=='u')
		{
			printf("no\n");
			continue;
		}
		for(i=0;i<n;i++)
		{
			flag=0;
			while(s[i]=='a'||s[i]=='e'||s[i]=='i'||s[i]=='o'||s[i]=='u')
			{
				if(flag==0)
					sum++;
				i++;
				flag=1;
			}	
		}
		if(sum==2)
			printf("yes\n");
		else
			printf("no\n");
	} 
	return 0;
} 

3、遞增三元組的中心
【問題描述】
在數列 a[1], a[2], …, a[n] 中,如果對於下標 i, j, k 滿足 0<i<j<k<n+1 且 a[i]<a[j]<a[k],則稱 a[i], a[j], a[k] 爲一組遞增三元組,a[j]爲遞增三元組的中心。
給定一個數列,請問數列中有多少個元素可能是遞增三元組的中心。
【輸入格式】
輸入的第一行包含一個整數 n。
第二行包含 n 個整數 a[1], a[2], …, a[n],相鄰的整數間用空格分隔,表示給定的數列。
【輸出格式】
輸出一行包含一個整數,表示答案。
【樣例輸入】
5
1 2 5 3 5
【樣例輸出】
2
【樣例說明】
a[2] 和 a[4] 可能是三元組的中心。
【評測用例規模與約定】
對於 50% 的評測用例,2 <= n <= 100,0 <= 數列中的數 <= 1000。
對於所有評測用例,2 <= n <= 1000,0 <= 數列中的數 <= 10000。
【解題思路】這個題思路很明確,就是要找滿足的遞增三元組且中心數只能出現一次,用book[]標記一下。

#include<stdio.h>
#include<string.h>
int a[1010],book[1010];
int main()
{
	int i,j,k,m,n,sum;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
	memset(book,0,sizeof(book));
	sum=0;
	for(i=1;i<=n;i++)
		for(j=i+1;j<=n;j++)
			for(k=j+1;j<=n;j++)
			{
				if(a[i]<a[j]&&a[j]<a[k]&&book[a[j]]==0)
				{
					book[a[j]]=1;
					sum++;
				}
			}
	printf("%d\n",sum);
	return 0;
			
}

4、種草問題

【問題描述】
小明有一塊空地,他將這塊空地劃分爲 n 行 m 列的小塊,每行和每列的長度都爲 1。
小明選了其中的一些小塊空地,種上了草,其他小塊仍然保持是空地。
這些草長得很快,每個月,草都會向外長出一些,如果一個小塊種了草,則它將向自己的上、下、左、右四小塊空地擴展,這四小塊空地都將變爲有草的小塊。
請告訴小明,k 個月後空地上哪些地方有草。
【輸入格式】
輸入的第一行包含兩個整數 n, m。
接下來 n 行,每行包含 m 個字母,表示初始的空地狀態,字母之間沒有空格。如果爲小數點,表示爲空地,如果字母爲 g,表示種了草。
接下來包含一個整數 k。
【輸出格式】
輸出 n 行,每行包含 m 個字母,表示 k 個月後空地的狀態。如果爲小數點,表示爲空地,如果字母爲 g,表示長了草。
【樣例輸入】
4 5
.g...
.....
..g..
.....
2
【樣例輸出】
gggg.
gggg.
ggggg
.ggg.
【評測用例規模與約定】
對於 30% 的評測用例,2 <= n, m <= 20。
對於 70% 的評測用例,2 <= n, m <= 100。
對於所有評測用例,2 <= n, m <= 1000,1 <= k <= 1000。
【解題思路】這是一個典型的bfs搜索問題,給n×m的字符矩陣,'g'表示種草,'.' 表示空地,每個月草都會向上、下、左、右擴展,然後再過一個月新長出來的草又去向上下左右擴展,直到k月。首先把草換一個字符#表示,然後找第一個月的草#,把#周圍的空地都計爲g,while循環,直到K月。
注:這題我自己試了好多實例都過了

#include<stdio.h>
#include<string.h>
char s[1100][1100];
int n,m;
void fn(int x,int y);
int main()
{
	int i,j,k;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		getchar();
		for(i=0;i<n;i++)
			scanf("%s",s[i]);
		scanf("%d",&k);
		while(k--)
		{
			for(i=0;i<n;i++)
				for(j=0;j<m;j++)
					if(s[i][j]=='g')//先把草換一個字符表示
						s[i][j]='#';
			for(i=0;i<n;i++)
				for(j=0;j<m;j++)
				{
					if(s[i][j]=='#')//在矩陣中去尋找
						fn(i,j);
				}
		}
		for(i=0;i<n;i++)
			for(j=0;j<m;j++)
				if(s[i][j]=='#')
					s[i][j]='g';
		for(i=0;i<n;i++)
			printf("%s\n",s[i]);
	}
	return 0;
}
void fn(int x,int y)
{
	int i,j,k,tx,ty;
	int next[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
	for(i=0;i<4;i++)
	{
		tx=x+next[i][0];
		ty=y+next[i][1];
		if(tx<0||tx>n||ty<0||ty>m)
			continue;
		if(s[tx][ty]=='.')//上下左右遇到空地就計爲草g
			s[tx][ty]='g';
	}	
}

5、奇怪的數列

【問題描述】
小明想知道,滿足以下條件的正整數序列的數量:
1. 第一項爲 n;
2. 第二項不超過 n;
3. 從第三項開始,每一項小於前兩項的差的絕對值。
請計算,對於給定的 n,有多少種滿足條件的序列。
【輸入格式】
輸入一行包含一個整數 n。
【輸出格式】
輸出一個整數,表示答案。答案可能很大,請輸出答案除以10000的餘數。
【樣例輸入】
4
【樣例輸出】
7
【樣例說明】
以下是滿足條件的序列:
4 1
4 1 1
4 1 2
4 2
4 2 1
4 3
4 4
【評測用例規模與約定】
對於 20% 的評測用例,1 <= n <= 5;
對於 50% 的評測用例,1 <= n <= 10;
對於 80% 的評測用例,1 <= n <= 100;
對於所有評測用例,1 <= n <= 1000。
【解題思路】這個題看着簡單其實很麻煩,不過要考慮50%的樣例的話,就可以過,我猜測如果要過100%樣例可能要用dp;
我第一次寫的是利用模擬的思想:

//每次去保留滿足條件的最後兩個數
#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
	int i,j,m,k,n,t,sum,l;
	int a[1100],b[1100],c[1100],d[1100];
	while(scanf("%d",&n)!=EOF)
	{
		sum=n;
		for(i=1;i<=n;i++)
			a[i]=i;
		k=1;
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
			{
				if(abs(n-a[i])>a[j])
				{
					c[k]=a[i];
					d[k++]=a[j];
					sum++;
				}		
			}
		t=k-1;
		while(t!=0)
		{
			k=1;
			for(i=1;i<=t;i++)
			{
				a[i]=c[i];
				b[i]=d[i];
			}
			for(i=1;i<=t;i++)
			{
				for(l=1;l<abs(a[i]-b[i]);l++)
				{
					c[k]=b[i];
					d[k++]=l;
					sum++;
				}
			}
			t=k-1;
		}			
		printf("%d\n",sum%10000);
	} 
	return 0;
}


最後優化一下,發現用遞歸的思想更簡單:

//還是和剛剛一樣的思想,保留滿足條件的最後兩個數,一直的不滿足條件,遞歸結束
#include<stdio.h>
#include<math.h>
int fn(int a,int b);
int sum;
int main()
{
	int i,j,k,m,n;
	while(scanf("%d",&n)!=EOF)
	{
		sum=0;
		for(i=1;i<=n;i++)
			fn(n,i);
		printf("%d\n",sum%10000);
	}
	return 0;
}
int fn(int a,int b)
{
	int i;
	for(i=1;i<fabs(a-b);i++)
		fn(b,i);
	sum=(sum+1)%10000;	
}

6、晚會節目
【問題描述】
小明要組織一臺晚會,總共準備了 n 個節目。然後晚會的時間有限,他只能最終選擇其中的 m 個節目。
這 n 個節目是按照小明設想的順序給定的,順序不能改變。
小明發現,觀衆對於晚上的喜歡程度與前幾個節目的好看程度有非常大的關係,他希望選出的第一個節目儘可能好看,在此前提下希望第二個節目儘可能好看,依次類推。
小明給每個節目定義了一個好看值,請你幫助小明選擇出 m 個節目,滿足他的要求。
【輸入格式】
輸入的第一行包含兩個整數 n, m ,表示節目的數量和要選擇的數量。
第二行包含 n 個整數,依次爲每個節目的好看值。
【輸出格式】
輸出一行包含 m 個整數,爲選出的節目的好看值。
【樣例輸入】
5 3
3 1 2 5 4
【樣例輸出】
3 5 4
【樣例說明】
選擇了第1, 4, 5個節目。
【評測用例規模與約定】
對於 30% 的評測用例,1 <= n <= 20;
對於 60% 的評測用例,1 <= n <= 100;
對於所有評測用例,1 <= n <= 100000,0 <= 節目的好看值 <= 100000。
【解題思路】這個題我的理解就是選擇m個好看值大的節目,不過這m個好看的節目要考慮先後順序輸出。
注意:這個題我用的是雙重循環,只考慮過部分樣例

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int a[110000],b[110000],c[110000],book[110000];
int main()
{
	int i,j,k,n,m,t;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(book,0,sizeof(book));
		t=m;
		for(i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			b[i]=a[i];
		}
		sort(b,b+n+1);
		k=n;
		for(i=1;i<=m;i++)
			c[i]=b[k--];
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=m;j++)
			{
				if(a[i]==c[j]&&book[c[j]]==0)
				{
					book[c[j]]=1;
					printf("%d",a[i]);
					if(t>1)
						printf(" ");
					t--;
					break;
				}
			}
		}
		printf("\n");	
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章