第四届蓝桥杯真题

注来源:以下为观看来之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++;

 

posted @ 2018-03-20 20:46  让你一生残梦  阅读(362)  评论(0编辑  收藏  举报