2021-01-15

13年蓝B题个人总

  1. 大数学家高斯有个好习惯:无论如何都要记日记。 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
    后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
    高斯出生于:1777年4月30日。
    在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。
    高斯获得博士学位的那天日记上标着:8113 请你算出高斯获得博士学位的年月日。
    由于这题的数字给的不是很大,我在草稿纸上计算了一下就得出了结果:1799-07-16(注意格式)。
  2. 第39级台阶(未解决)
    小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!
    站在台阶前,他突然又想着一个问题:
    如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完39级台阶,有多少种不同的上法呢?
    请你利用计算机的优势,帮助小明寻找答案。`
    这道题没有看清题意,以为就是个递归问题,结果就大错特错了。
    错误代码:

```cpp
#include<stdio.h>
int main()
{
	int a[45]={0};
	a[1]=1;
	a[2]=2;
	for(int i=3;i<=39;i++)
	a[i]=a[i-1]+a[i-2];
	printf("%d",a[39]);
	return 0;
} 

 3. 
标题:三部排序

    一般的排序有许多经典算法,如快速排序、希尔排序等。

    但实际应用时,经常会或多或少有一些特殊的要求。我们没必要套用那些经典算法,可以根据实际情况建立更好的解法。

    比如,对一个整型数组中的数字进行分类排序:

    使得负数都靠左端,正数都靠右端,0在中部。注意问题的特点是:负数区域和正数区域内并不要求有序。可以利用这个特点通过1次线性扫描就结束战斗!!

    以下的程序实现了该目标。

    其中x指向待排序的整型数组,len是数组的长度。

void sort3p(int* x, int len)
{
	int p = 0;
	int left = 0;
	int right = len-1;
	
	while(p<=right){
		if(x[p]<0){
			int t = x[left];
			x[left] = x[p];
			x[p] = t;
			left++;
			p++;
		}
		else if(x[p]>0){
			int t = x[right];
			x[right] = x[p];
			x[p] = t;
			right--;			
		}
		else{
			__________________________;  //填空位置
		}
	}
	
}

   如果给定数组:
   25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0
   则排序后为:
   -3,-2,-16,-5,0,0,0,21,19,33,25,16,18,25
	


请分析代码逻辑,并推测划线处的代码,通过网页提交
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!

(这道题我认为是十分简单的但还是看了好久)
首先读题,把负数放左边,正数放右边,0放中间(其实就是正数和负数都动,0不动)
so答案:p++;
             x[p]=x[p];(可省略)
4.标题:错误票据

    某涉密单位下发了某种票据,并要在年终全部收回。

    每张票据有唯一的ID号。全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。

    因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。

    你的任务是通过编程,找出断号的ID和重号的ID。

    假设断号不可能发生在最大和最小号。

要求程序首先输入一个整数N(N<100)表示后面数据行数。
接着读入N行数据。
每行数据长度不等,是用空格分开的若干个(不大于100个)正整数(不大于100000)
每个整数代表一个ID号。

要求程序输出1行,含两个整数m n,用空格分隔。
其中,m表示断号ID,n表示重号ID
<font clolor=red>
思路:首先这些数都是不大于100000的,所以可以设置一个比100000略大的数组(数组初始化为零),找出输入数据的最大最小值,让i=最小值,从最小到最大都遍历一遍,每次出现的a[i]都加一,其中为零的就是漏的,为二的就是重复的。

```cpp
#include<bits/stdc++.h>
using namespace std;
int a[100000]={0},b[200];
int main() 
{
	int i=0,max=0,min=100000,n,j,k=0,c=0,l=0;
	scanf("%d",&n);
	while(n--) 
	{
	while(cin>>b[++i])
	{
       k=i;
       if(b[i]>max)
       max=b[i];
       if(b[i]<min)
       min=b[i];
	}
	}
	for(i=1;i<=k;i++)
		   {
		   	a[b[i]]++;
		   	if(a[b[i]]==2)
		   	c=b[i];
		   }
		   for(i=min;i<=max;i++)
		   {
		   	if(a[i]==0)
			   {
			l=i;
			break;
		   	}
		   }	
	 printf("%d %d\n",l,c);
	 return 0;
}


  1. 题目标题:翻硬币

    小明正在玩一个“翻硬币”的游戏。

    桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。

    比如,可能情形是:oo*oooo

    如果同时翻转左边的两个硬币,则变为:oooo***oooo

    现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
    我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求:

程序输入:
两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000

程序输出:
一个整数,表示最小操作步数
思路:可以先草稿纸上找找规律,发现如果是奇数个不同的话这种情况是无法最终相同的,假如有四个不同,就等于第二个不同的下标-第一个不同+第四个-第三个。那么解决方法就是记录下当不同的下标,用一个数组储存,共有n个不同,从1~n,用数组[i+1]-i加上后面的。(注意减完i要自增一次,不然会多加)。

#include<stdio.h>
#include<string.h>
char a[1050]={0},b[1050]={0};
int main()
{
	int c[1050]={0},k=0,sum=0;
	scanf("%s%s",a,b);
	int n1=strlen(a);
	for(int i=0;i<n1;i++)
		{
			if(b[i]!=a[i])
			c[++k]=i,s++;
		}
		for(int j=1;j<=k;j++)
		{
		sum+=c[j+1]-c[j];
		j++;
		continue;
		}
		printf("%d\n",sum);
	return 0;
}

第一次写博客,如果哪里有错误或者可以更好的解决欢迎大家指教。
感觉蓝桥杯的题有难有易,取舍十分重要,还有题意也要认真仔细读懂,如果没认真读完很可能后面又要返回读题,填空题实在是有点难为我,看了n久还是一脸懵逼,不管怎样,干就完了!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值