牛客网解题-2017网易雷火实习生笔试题

序言

明天网易游戏的笔试,先做一套练习卷熟悉一下。

一共4道编程:字符串编码 + 最大和 + 推箱子 + 赛马

第三题在下篇文章中单独解答,这里仅介绍1,2,4题。


1. 字符串编码

  • 题目描述

    给定一个字符串,请你将字符串重新编码,将连续的字符替换成“连续出现的个数+字符”。比如字符串AAAABCCDAA会被编码成4A1B2C1D2A。

  • 输入输出描述

    输入:每个测试输入包含1个测试用例
    每个测试用例输入只有一行字符串,字符串只包括大写英文字母,长度不超过10000。

    输出:输出编码后的字符串

  • 输入输出描述

输入:AAAABCCDAA

输出:4A1B2C1D2A
  • 解题思路

    提取连续字符个数,不过关键在于表示时数字字符转换以及数字字符对应正确

  • 代码(C语言,AC)

#include 
#include 
#include 

int NumInvert(int n, int *len)
{
    *len = 0;
    int m = n;
    while (m != 0)
    {
        m = m / 10;
        (*len)++;
    }
    int array[*len];
    int i = 0;
    while (n != 0)
    {
        array[i++] = n % 10;
        n = n / 10;
    }
    i = 0;
    int length = *len - 1;
    while (i < *len)
    {
        n += (int)ceil(array[i++]*pow((double)10, (double)length));
        length--;
    }
    return n;
}


int main()
{
    char string[10000];
    scanf("%s", string);
    char jilu[15000];
    int i = 0, flag = 0, count = 0, length = 0;
    char zifu = string[flag];
    while (string[flag] != '\0')
    {
        while (string[flag] == zifu)
        {
            count++;
            flag++;
        }
        count = NumInvert(count, &length);
        while (length > 0)          //对应位字符提取
        {
            jilu[i++] = count % 10 + '0';
            count = count / 10;
            length--;
        }
        jilu[i++] = zifu;
        zifu = string[flag];
    }
    int len = strlen(jilu);
    i = 0;
    for (; i < len; i++)
    {
        printf("%c", jilu[i]);
    }
    return 0;
}


2. 最大和

  • 题目描述

    在一个N*N的数组中寻找所有横,竖,左上到右下,右上到左下,四种方向的直线连续D个数字的和里面最大的值

  • 输入输出描述

    输入:
    每个测试输入包含1个测试用例,第一行包括两个整数 N 和 D :
    3 <= N <= 100
    1 <= D <= N
    接下来有N行,每行N个数字d:
    0 <= d <= 100

    输出:
    输出一个整数,表示找到的和的最大值

  • 输入输出描述

输入:
4 2
87 98 79 61
10 27 95 70
20 64 73 29
71 65 15 0

输出:193
  • 解题思路

    对应找出横向,纵向,左上到右下,右上到左下的最大值比较

  • 代码(C语言,21% AC)

    这题并没有AC,如果读者发现其中问题出处,欢迎指出交流

#include 

int main()
{
    int N, D;
    scanf("%d %d", &N, &D);
    int arr[N][N];                          //如果定义在scanf之前,编译器停止工作
    int i, j;
    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            scanf("%d", &arr[i][j]);
        }
    }
    //横向比较
    int max_heng = 0;
    int count, flag, max_temp;
    i = 0;
    while (i < N)
    {
        count = 0; flag = 0; max_temp = 0;
        for (flag = 0; flag < D; flag++)
        {
            max_temp = max_temp + arr[i][flag];
        }
        while (flag < N)
        {
            if (max_temp + arr[i][flag] - arr[i][count] > max_temp)
                max_temp = max_temp + arr[i][flag] - arr[i][count];
            flag++;
            count++;
        }
        if (max_temp > max_heng)
            max_heng = max_temp;
        i++;
    }

    //纵向比较
    int max_zong = 0;
    j = 0;
    while (j < N)
    {
        count = 0; flag = 0; max_temp = 0;
        for (flag = 0; flag < D; flag++)
            max_temp = max_temp + arr[flag][j];
        while (flag < N)
        {
            if (max_temp + arr[flag][j] - arr[count][j] > max_temp)
                max_temp = max_temp + arr[flag][j] - arr[count][j];
            flag++;
            count++;
        }
        if (max_temp > max_zong)
            max_zong = max_temp;
        j++;
    }

    //左上到右下
    int max_zuo = 0;
    i = 0; j = 0;
    int jishu, row, column;
    for (i = 0; i <= N - D; i++)
    {
        for (j = 0; j <= N - D; j++)
        {
            max_temp = 0; jishu = 0; row = i, column = j;
            for (jishu = 0; jishu < D; jishu++)
            {
                max_temp = max_temp + arr[row][column];
                row++;
                column++;
            }
            if (max_zuo < max_temp)
                max_zuo = max_temp;
        }
    }

    //右上到左下
    int max_you = 0;
    i = 0; j = N - 1;
    for (i = 0; i <= N - D; i++)
    {
        for (j = N - 1; j >= D - 1; j--)
        {
            max_temp = 0; jishu = 0; row = i, column = j;
            for (jishu = 0; jishu < D; jishu++)
            {
                max_temp = max_temp + arr[row][column];
                row++;
                column--;
            }
            if (max_you < max_temp)
                max_you = max_temp;
        }
    }

    int maximum = max_heng;
    if (max_zong > maximum)
        maximum = max_zong;
    if (max_zuo > maximum)
        maximum = max_zuo;
    if (max_you > maximum)
        maximum = max_you;
    printf("%d\n", maximum);
    return 0;
}


4. 赛马

  • 题目描述

    在一条无限长的跑道上,有N匹马在不同的位置上出发开始赛马。当开始赛马比赛后,所有的马开始以自己的速度一直匀速前进。每匹马的速度都不一样,且全部是同样的均匀随机分布。在比赛中当某匹马追上了前面的某匹马时,被追上的马就出局。 请问按以上的规则比赛无限长的时间后,赛道上剩余的马匹数量的数学期望是多少

  • 输入输出描述

    输入:
    每个测试输入包含1个测试用例
    输入只有一行,一个正整数N
    1 <= N <= 1000

    输出:
    输出一个浮点数,精确到小数点后四位数字,表示剩余马匹数量的数学期望

  • 输入输出描述

输入:
1
2

输出:
1.0000
1.5000
  • 解题思路

    这是一个离散分布求数学期望的数学模型,重要的是求出剩余马匹数和对应的概率值,但是求概率值的时候发现,到3匹马以上就不太好分析了。

    我们从马的速度角度去考虑,马的速度总可以从大到小排列 v1 > v2 > v3 >… > vN,不同速度的马存活与否和马出现的位置直接相关。

    速度最快v1马无论出现在什么位置都能存活,存活概率为1
    速度v2只有出现在最快马之前才能存活,由于马的速度是均匀随机分布,就是说v2在最快马之前之后等概,为1/2
    速度v3出现在v2之前、v2 v1之间、v1之后也是等概,为1/3

    可以通过1 + 1/2 + 1/3 + … + 1/n 求有马匹数量的数学期望

  • 代码(C语言,AC)

#include 

double HorseE(int num)
    {
    int i = 1;
    double qiwang = 0;
    while (i <= num)
        {
        qiwang = qiwang + (double)1 / (double)i;
        i++;
    }
    return qiwang;
}

int main()
    {
    int n;
    scanf("%d", &n);
    double expectation = HorseE(n);
    printf("%.4lf", expectation);
    return 0;
}



2017.09.15

你可能感兴趣的:(牛客网解题)