2017网易雷火实习生招聘编程题

题目来源:牛客网https://www.nowcoder.com/profile/7952866/test/7775568/76265

1.字符串编码

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

输入例子:

AAAABCCDAA

输出例子:

4A1B2C1D2A

思路比较简单,只需要遍历字符串,对每一个单独的字符设置一个初始值为1的计数器,然后比较它和相邻的字符是否相同,如果相同则加1,直到遇到不同的字符,输出当前计数器的值并重置为1。

测试代码如下:

#include <cstdio>
#include <string>
#include <iostream>

using namespace std;

string num = "0123456789";

string intToString(int n) 
{
    //int转成string,比如 12转为‘12’
    string str = "";
    while (n) 
    {
        str = num[n % 10] + str;
        n = n / 10;
    }
    return str;
}

string solve(string str) 
{
    int len = str.size();
    int i = 0;
    char cur;
    int cnt;
    string ans = "";
    //从字符串头部开始依次遍历
    while (i < len) 
    {
        cur = str[i];
        cnt = 0;
        int j = 0;
        for (j = i; j < len; j++) 
        {    // 从当前位置开始检索
            if (str[j] == cur) 
            {
                cnt++;
            }
            else if (str[j] != cur) 
            {
                ans = ans + intToString(cnt);
                ans = ans + cur;
                i = j;                      // 从i = j这个位置再开始检索
                break;
            }
        }
        if (j == len) 
        {
            ans = ans + intToString(cnt);
            ans = ans + cur;
            break;
        }
    }
    return ans;
}

int main()
{
    string str;
    while (cin >> str)
    {
        string ans = solve(str);
        cout << ans << endl;
    }
    return 0;
}

测试结果:

2.赛马

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

输入描述:

每个测试输入包含1个测试用例

输入只有一行,一个正整数N

1 <= N <= 1000

输出描述:

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

输入例子:

1

2

输出例子:

1.0000

1.5000

思路分析:题目看上去有点费解,个人更感觉像是一道智力题。我们假设有N匹马赛跑,最后剩下的那个是冠军。注意题目中说每个马的速度不一样,这就说明最后只会剩下一个马,不可能出现并列的情况。另外数学期望的意思就是如果这匹马的编号是i,那P(i)表示i是冠军的概率,就是数学期望。可以这样想一下:如果只有一匹马,那么这匹马肯定是冠军,数学期望显然是1。如果有两匹马,那么某一匹马是冠军的概率是0.5,某一时刻其中一个马被淘汰了,那么另一个马的数学期望变成1,相加就是1.5。依次类推,如果刚开始有N匹马,P(i) = 1 / N,某一时刻P(i) = 1 / (N - 1)、1/(N - 2)......所以这道题的答案就是计算1 + 1  /  2 + 1 / 3 + 1 / 4 + ... + 1 / N的和,就是调和级数。

测试代码如下:

#include <cstdio>
//调和级数
int main() 
{
    int n;
    while (scanf_s("%d", &n) != EOF)
    {
        double sum = 0.0;
        for (int i = 1; i <= n; i++) 
        {
            sum = sum + 1.0 / i;
        }
        printf("%.4lf\n", sum);
    }
    return 0;
}

测试结果:

3.最大和

在一个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

思路:直接从行、列、左上到右下,右上到左下,四种方向暴力搜索

测试代码:

#include <iostream>

#define MAX 100 + 10

int Max = 0;

bool check1(int x, int y, int d, int n) 
{
    if (x + d - 1 > n) 
        return false;
    if (y + d - 1 > n) 
        return false;
    return true;
}


bool check2(int x, int y, int d, int n) 
{
    if (x + d - 1 > n) 
        return false;
    if (y - d < 0)
        return false;
    return true;
}

int main() 
{
    int n, d;
    while (scanf_s("%d%d", &n, &d) != EOF) 
    {
        Max = 0;
        int arr[MAX][MAX];

        for (int i = 1; i <= n; i++) 
        {
            for (int j = 1; j <= n; j++) 
            {
                scanf_s("%d", &arr[i][j]);
            }
        }

        // 先从每行开始找
        for (int row = 1; row <= n; row++)
        {
            for (int i = 1; i <= n - d + 1; i++)
            {
                int sum = 0;
                for (int j = i; j < d + i; j++) 
                {
                    sum = sum + arr[row][j];
                }
                if (sum > Max)
                    Max = sum;
            }
        }

        // 再从每列开始找
        for (int col = 1; col <= n; col++) 
        {
            for (int i = 1; i <= n - d + 1; i++)
            {
                int sum = 0;
                for (int j = i; j < d + i; j++)
                {
                    sum = sum + arr[j][col];
                }
                if (sum > Max) 
                    Max = sum;
            }
        }

        // 再从左上到右下对角线开始找
        for (int i = 1; i <= n; i++) 
        {
            for (int j = 1; j <= n; j++) 
            {     // 从i,j起点开始找
                int x = i;
                int y = j;
                if (check1(x, y, d, n)) 
                {
                    int cnt = 0;
                    int sum = 0;
                    while (cnt < d) 
                    {
                        sum = sum + arr[x][y];
                        cnt++;
                        x++;
                        y++;
                    }

                    if (sum > Max)
                        Max = sum;
                }
            }
        }


        // 再从右上到左下对角线开始找
        for (int i = 1; i <= n; i++) 
        {
            for (int j = 1; j <= n; j++) 
            {     // 从i,j起点开始找
                int x = i;
                int y = j;
                if (check2(x, y, d, n)) 
                {
                    int cnt = 0;
                    int sum = 0;
                    while (cnt < d)
                    {
                        sum = sum + arr[x][y];
                        cnt++;
                        x++;
                        y--;
                    }
                    if (sum > Max) 
                        Max = sum;
                }
            }
        }

        printf("%d\n", Max);
    }
    return 0;
}

测试结果如下:

4.推箱子

大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个N*M的地图上,有1个玩家、1个箱子、1个目的地以及若干障碍,其余是空地。玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去。如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里。当箱子被推到目的地以后,游戏目标达成。现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成。 

输入描述:

每个测试输入包含1个测试用例

第一行输入两个数字N,M表示地图的大小。其中0<N,M<=8。

接下来有N行,每行包含M个字符表示该行地图。其中 . 表示空地、X表示玩家、*表示箱子、#表示障碍、@表示目的地。

每个地图必定包含1个玩家、1个箱子、1个目的地。

输出描述:

输出一个数字表示玩家最少需要移动多少步才能将游戏目标达成。当无论如何达成不了的时候,输出-1。

输入例子:

4 4

....

..*@

....

.X..

6 6

...#..

......

#*##..

..##.#

..X...

.@#...

输出例子:

3

11

思路:利用BFS,每一步有4中情况,用四维数组记录每一个人和箱子所在位置的状态,如果之前出现过这种状态,直接跳过,否则计数加一,一直遍历,若队列为空还没有输出,则无法到达。否则可以到达。by:http://blog.csdn.net/njudongchen/article/details/61415043

测试代码如下:

#include <iostream>
#include <string>
#include <queue>
#include <vector>

using namespace std;
struct humanbox
{
    //创建一个结构体:人和箱子的坐标
    int hx, hy, bx, by;
    humanbox(int x, int y, int bbx, int bby) :hx(x), hy(y), bx(bbx), by(bby)
    {};
};
int main()
{
    int n, m;
    cin >> n >> m;
    vector<vector<int>> map(n, vector<int>(m, 0));
    int hx, hy;  //玩家起点坐标
    int bx, by;  //箱子坐标
    int endx, endy; //目的地坐标
    for (int i = 0; i != n; ++i)
    {
        //更新地图map
        string str;
        cin >> str;
        for (int j = 0; j != m; ++j)
        {
            if (str[j] == 'X')
            {
                map[i][j] = 'X';
                hx = i;
                hy = j;
            }
            else if (str[j] == '#')
                map[i][j] = '#';
            else if (str[j] == '@')
            {
                map[i][j] = '@';
                endx = i;
                endy = j;
            }
            else if (str[j] == '*')
            {
                map[i][j] = '*';
                bx = i;
                by = j;
            }
        }
    }
    //枚举四个方向:向右走、向左走、向下走、向上走
    int stepx[4] = { 0, 0, 1, -1 };
    int stepy[4] = { 1, -1, 0, 0 };

    //更新步数
    int count[10][10][10][10] = { 0 };

    queue<humanbox> que;
    que.push(humanbox(hx, hy, bx, by));
    count[hx][hy][bx][by] = 1;

    while (!que.empty())
    {
        humanbox top_que = que.front();
        que.pop();
        if (top_que.bx == endx&&top_que.by == endy)
        {
            //到达终点
            cout << (count[top_que.hx][top_que.hy][top_que.bx][top_que.by]) - 1;
            //输出减1是因为起始从1开始
            cout<< endl;
            return 0;
        }
        for (int i = 0; i != 4; ++i)
        {
            int hnx = top_que.hx + stepx[i];
            int hny = top_que.hy + stepy[i];
            if (hnx<0 || hny<0 || hnx >= n || hny >= m || map[hnx][hny] == '#')
                //当越界或者遇到障碍物
                continue;
            if (hnx == top_que.bx&&hny == top_que.by)
            {
                //当玩家遇到箱子
                int bnx = top_que.bx + stepx[i];
                int bny = top_que.by + stepy[i];
                if (bnx<0 || bny<0 || bnx >= n || bny >= m 
                    || map[bnx][bny] == '#') 
                    //当箱子越界或者遇到障碍物
                    continue;
                if (count[hnx][hny][bnx][bny]) 
                    continue;
                count[hnx][hny][bnx][bny] = count[top_que.hx]
                    [top_que.hy][top_que.bx][top_que.by] + 1;
                que.push(humanbox(hnx, hny, bnx, bny));
            }
            else
            {
                if (count[hnx][hny][top_que.bx][top_que.by])
                    continue;
                count[hnx][hny][top_que.bx][top_que.by] 
                    = count[top_que.hx][top_que.hy][top_que.bx][top_que.by] + 1;
                que.push(humanbox(hnx, hny, top_que.bx, top_que.by));
            }
        }
    }
    cout << -1 << endl;
    return 0;
}

测试结果:

 

 

posted @ 2017-04-08 11:26  walanwalan  阅读(372)  评论(0编辑  收藏  举报