13年蓝B题个人总
- 大数学家高斯有个好习惯:无论如何都要记日记。 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。
高斯获得博士学位的那天日记上标着:8113 请你算出高斯获得博士学位的年月日。
由于这题的数字给的不是很大,我在草稿纸上计算了一下就得出了结果:1799-07-16(注意格式)。 - 第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;
}
-
题目标题:翻硬币
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。我们用 * 表示正面,用 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久还是一脸懵逼,不管怎样,干就完了!!!