2018年第九届蓝桥杯省赛C++B组部分题解

自己感觉本届蓝桥杯的题目还是不错的,就是坑点比较多,要认真读题啊!!!


以下题解都是我后来补得……发现自己错了很多。。。如果有代码或结果不对还请指正,多谢~


至于题目可以去2018年蓝桥杯C++、java B组真题下载。




第1题:



题目大意:

2000年的1月1日,是那一年的第1天。那么,2000年的5月4日,是那一年的第几天?



思路:

最快的思路是用excel直接将两个日期做差得出结果,注意结果要 +1. 当然也可以编程求解。



答案:125




第2题:



题目大意:

每个汉字可以用 16*16的矩阵编码显示,给出10个汉字的编码信息,根据汉字意思作答。



思路:

利用移位操作算出二进制数的每一位对应的是 0 还是 1,然后输出即可。为了方便查看,可以将为 0 的换成空格输出。




代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
	int i,j,k,a,pos,mp[16];
	for(i=0;i<10;i++)
	{
		for(j=0;j<32;j++)
		{
			scanf("%d",&a);
			if(j%2==0)
			{
				pos=8;
				for(k=0;k<8;k++)
				{
					pos--;
					if(a%2==0) mp[pos]=0;
					else mp[pos]=1;
					a>>=1;
				}
				for(k=0;k<8;k++) 
				{
					if(mp[k]==0) printf(" ");
					else printf("1");
				}
			}
			else
			{
				pos=16;
				for(k=8;k<16;k++)
				{
					pos--;
					if(a%2==0) mp[pos]=0;
					else mp[pos]=1;
					a>>=1;
				}
				for(k=8;k<16;k++)
				{
					if(mp[k]==0) printf(" ");
					else printf("1");
				}
				printf("\n");
			}
		}
	}
	int ans=1;
	for(i=0;i<9;i++)
	{
		ans*=9;
		printf("ans=%d\n",ans);
	}
	return 0;
}


答案:387420489 ,注意是 9的 9次方,不是 9*9……




第3题:



题目大意:

给你100个数,问它们乘积结尾 0 的个数。



思路:

可以无脑用 java大数解决。还有种思路是计算每个数因子中 5 的个数,然后求和。


根据算数基本定理(唯一分解定理),每个数都可以分解成若干个质因子相乘的结果。又因为 2*5 =10,一个数的结尾 0 的个数肯定是其质因子分解中 5 的幂次和 2 的幂次的最小值。显然 5 的个数应该小于 2 的个数,故如果数为 5 的倍数,可以求其 5 的因子的幂次。



代码:

#include<stdio.h>
int main()
{
	int i,n,ans;
	ans=0;
	for(i=0;i<100;i++)
	{
		scanf("%d",&n);
		while(n%5==0)
		{
			n/=5;
			ans++;
		}
	}
	printf("%d\n",ans);
	return 0;
}



答案:31




第4题:



题目大意:

用 3块手机测试手机的耐摔程度,问采用最佳方法时最小的测试次数。注意只有3块手机,并且如果手机没摔坏可以继续用。



思路:

由于当时没看到只有 3块手机的条件,我直接当成简单的二分题做了……本题不会,略过……




第5题:



题目大意:

代码填空题。代码的作用是求区间第 k 大的数。



思路:

一般代码填空题都是考察递归,我们可以先算得代码正确运行的结果,然后凑这个结果,也方便验证对错。



看上面的代码,第一行是直接返回结果,说明找到了第 k 大的值,且 i-l+1 的位置就是结果。第三行明显是搜索的左区间。现在要补充第二行,第二行明显要搜索右区间,所以前三个参数可以确定了: a, i , r .  然后考虑递归,前 i-l+1 个数都比要找的位置 k 小,所以我们只需要在右区间寻找第 k-(i-l) 小的数即可。



答案: a,i,r,k-i+l




第6题



题目大意:

有三个等长的数组 A、B、C,请你统计有多少个三元组(i, j, k) 满足:

1. 1 <= i, j, k <= N  

2. Ai < Bj < Ck



思路:

注意是严格大于。如果没思路可以暴力求解,还是可以得点分的。


由于暴力时间复杂度为 O(n^3) ,会超时,所以我们考虑将前两个数组排序,然后对于 B 中的每个元素二分搜索 A中小于他的数的个数,再对于 C 中的每个元素二分搜索 B中小于他的数的个数。然后求和就是结果,具体看代码。



代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;

int a[100010],b[100010],c[100010],num1[100010],num2[100010];

int main()
{
	int i,j,n,pos;
	LL ans;
	while(~scanf("%d",&n))
	{
		for(i=0;i<n;i++) scanf("%d",&a[i]);
		for(i=0;i<n;i++) scanf("%d",&b[i]);
		for(i=0;i<n;i++) scanf("%d",&c[i]);
		sort(a,a+n);
		sort(b,b+n);
		for(i=0;i<n;i++)
		{
			pos=upper_bound(a,a+n,b[i]-1)-a;
			num1[i]=pos;
		}
		ans=0;
		for(i=0;i<n;i++)
		{
			pos=upper_bound(b,b+n,c[i]-1)-b;
			for(j=0;j<pos;j++) ans+=num1[j];
		}
		printf("%lld\n",ans);
	}
	return 0;
}




第7题:



题目大意:


根据以上螺旋曲线求出到某个点为止曲线的长度。



思路:

这种题最好找规律求解,每个人找的规律也会大不相同。


先只看 x,对于 x>0 和 x<0 两种情况计算螺旋曲线上横、下横、左竖、右竖的长度之和,可以利用等差数列求出前 n 项和。这是当 x 确定时曲线长度确定的部分。不确定的部分就是最左边(x<0时)或最右边(x>0时)竖着的长度。得出表达式后求和即可。


由于当时时间有限,我的代码不能处理 x=0 的情况,这个可以自己推导,以后若有空我会补上。



代码:

#include<stdio.h>
#include<string.h>
typedef long long LL;

int main()
{
	LL x,y,ans;
	while(~scanf("%lld%lld",&x,&y))
	{
		if(x==0) ans=0;
		else if(x<0)
		{
			x=-x;
			ans=x*x + x*(x-1) + (x-1)*(x-1) + x*(x-1);
			ans+=x-1+y;
		}
		else
		{
			ans=x*x + x*(x+1) + x*x + x*(x-1);
			ans+=x-y;
		}
		printf("%lld\n",ans);
	}
	return 0;
}



后面的题就懒得把代码都敲出来了。。。只说下思路吧。



第8题:



题目大意:

现在我们知道某个时间哪篇文章被点赞,求在一定时间段内,点赞数超过某个数量的文章编号。



思路:

我们要先把不同文章不同时间收到的赞给弄到一起,可以用 vector数组解决。然后对一篇文章的点赞时间排序,利用尺取法计算时间段 D 内收获的赞的数量,如果>k,则输出其编号。




第9题:



题目大意:

你有一张某海域NxN像素的照片,"."表示海洋、"#"表示陆地,因为海平面上升会淹没临海的区域(即上下左右至少有一个挨着海的),问有多少岛屿会被完全淹没。



思路:

这个题应该是用 DFS做,先一遍 DFS求出岛屿的个数,然后将临海的区域淹没,再一遍 DFS求出剩余岛屿的个数。


但是注意一点,一个岛屿部分被淹没后可能会形成多个岛屿……建议给每个岛屿编号,然后求编号减少的个数。

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值