第四届蓝桥杯真题
注来源:以下为观看来之http://www.cnblogs.com/OctoptusLian/p/8548852.html#commentform的博客,写的自我存档。注来源上面。
一、 高斯日记
题目描述:
大数学家高斯有个好习惯:无论如何都要记日记。
他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。
高斯获得博士学位的那天日记上标着:8113
请你算出高斯获得博士学位的年月日。
提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21
请严格按照格式,通过浏览器提交答案。
注意:只提交这个日期,不要写其它附加内容,比如:说明性的文字。
代码如下:
#include<stdio.h> #define num 8113 int main() { int year = 1777,month = 4,day = 30; int a[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; if(year % 4 ==0 && year % 100!=0 || year % 400 == 0) a[2] = 29; else a[2] = 28; for(int i = 1; i < num; i++) { day = day +1; if(day == a[month]+1) { month = month+1; day = 1; if(month >= 13) { year++; month = 1; if(year % 4 ==0 && year % 100!=0 || year % 400 == 0) a[2] = 29; else a[2] = 28; } } } printf("%d-%d-%d\n",year,month,day); return 0; }
题目答案:
1799-07-16
二、马虎的算式
题目描述:
小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。
有一次,老师出的题目是:36 x 495 = ?
他却给抄成了:396 x 45 = ?
但结果却很戏剧性,他的答案竟然是对的!!
因为 36 * 495 = 396 * 45 = 17820
类似这样的巧合情况可能还有很多,比如:27 * 594 = 297 * 54
假设 a b c d e 代表1~9不同的5个数字(注意是各不相同的数字,且不含0)
能满足形如: ab * cde = adb * ce 这样的算式一共有多少种呢?
请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。
满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。
答案直接通过浏览器提交。
注意:只提交一个表示最终统计种类数的数字,不要提交解答过程或其它多余的内容。
代码如下:
#include <stdio.h> int main() { int a,b,c,d,e,n=0; for (a=1; a<=9; a++) { for (b=1; b<=9; b++) { if (a==b) continue; for (c=1; c<=9; c++) { if((c==a)||(c==b)) continue; for (d=1; d<=9; d++) { if((d==a) || (d==b) || (d==c)) continue ; for (e=1; e<=9; e++) { if ((e==a)||(e==b)||(e==c)||(e==d)) continue; if ( (10*a+b)*(100*c+10*d+e)==(100*a+10*d+b)*(10*c+e)) n++; } } } } } printf("%d\n",n); return 0; }
题目答案:
142
三、第39级台阶 蓝桥杯
题目描述:
小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!
站在台阶前,他突然又想着一个问题:
如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完39级台阶,有多少种不同的上法呢?
请你利用计算机的优势,帮助小明寻找答案。
要求提交的是一个整数。
注意:不要提交解答过程,或其它的辅助说明文字。
思路:用dfs做,很容易就出来了。
伪代码:
结束条件是走了正好39级台阶,并且迈左脚数等于迈右脚数。
否则继续走
(因为不可能连续走两次右脚或者左脚,所以下面这个判断条件一定要加)
如果迈的左脚数大于迈的右脚数,则迈右脚(又分为迈右脚一步,迈右脚两步)
如果迈的左脚数小于等于迈的右脚数,则迈左脚(又分为迈左脚一步,迈左脚两步)
代码如下:
#include <stdio.h> int fun(int step,int position) { if(position == 39) { if(step%2==0) return 1; return 0; } if(position>39) return 0; return fun(step+1,position+1) + fun(step+1,position+2); } int main() { int number = 39; ///代表着跨了step步数,位置是position。 printf("%d\n",fun(1,1)+fun(1,2)); return 0; } 题目答案: 51167078
四、前缀判断
如下的代码判断 needle_start指向的串是否为haystack_start指向的串的前缀,如不是,则返回NULL。
比如:"abcd1234" 就包含了 "abc" 为前缀
char* prefix(char* haystack_start, char* needle_start) { char* haystack = haystack_start; char* needle = needle_start; while(*haystack && *needle){ if(______________________________) return NULL; //填空位置 } if(*needle) return NULL; return haystack_start; }
分析:
题目是实现判断是不是前缀问题。
信息点:1、while里面没有自加位置的符号
2、while里面要一个判断在某位置是不是相等
答案如下:
#include <stdio.h> char* prefix(char* haystack_start, char* needle_start) { char* haystack = haystack_start; char* needle = needle_start; while(*haystack && *needle){ if(*(haystack++)!=*(needle++)) return NULL; //填空位置 } if(*needle) return NULL; ///这个表示hatstack_start后面不够长 return haystack_start; ///这个表示返回haystack_start.代表着是他的前缀。 } int main() { char *haystack_start = "abcd1"; char* needle_start = "abcd"; printf("%s\n",prefix( haystack_start, needle_start)); return 0; }
题目答案:
*(haystack++) != *(needle++)
五、三部排序
题目描述:
一般的排序有许多经典算法,如快速排序、希尔排序等。
但实际应用时,经常会或多或少有一些特殊的要求。我们没必要套用那些经典算法,可以根据实际情况建立更好的解法。
比如,对一个整型数组中的数字进行分类排序:
使得负数都靠左端,正数都靠右端,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{ __________________________; //填空位置 } } }
代码如下:
#include <stdio.h> 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{///表示等于0 //x[left] == 0?p++:left = p++; p++; ///满足条件为: ///第一个left的位置要进行比较,因为p的位置为0 ///第二个left的原来位置为负数的话,要进行处理 ///第三个p要后移不然死循环 } } } int main() { //int x[] = {25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0}; int x[] = {0,0,0,-1,0,0,0,0,0,0}; sort3p(x,10); for(int i=0;i<10;i++) { printf("%d ",x[i]); } return 0; } 题目答案 x[left] == 0?p++:left = p++;或者p++;