今日头条笔试题

第一题

题面【深搜,搜索有多少个连通区域】:

世界杯球场,能容纳M*N个球迷。官方想统计观众中有多少个球队的球迷群体,最大的群体人数是多少?

球迷群体选座有以下特征:

  • 同球队球迷会选择相邻座位,不同球队会选择不相邻的座位。(注解:相邻包括前后左右、斜对角相邻,即8个搜索方向);
  • 在M*N个数中,0代表没人,1代表有人;
输入:
10,10
0,0,0,0,0,0,0,0,0,0
0,0,0,1,1,0,1,0,0,0
0,1,0,0,0,0,0,1,0,1
1,0,0,0,0,0,0,0,1,1
0,0,0,1,1,1,0,0,0,1
0,0,0,0,0,0,1,0,1,1
0,1,1,0,0,0,0,0,0,0
0,0,0,1,0,1,0,0,0,0
0,0,1,0,0,1,0,0,0,0
0,1,0,0,0,0,0,0,0,0
输出:
6, 8
代码:
#include 
#include 
#include 

#define CLEAR(name, init) memset(name, init, sizeof(name));
const int MAXN = (int) 1e3 + 5;
using namespace std;

int n, m;
int maxSize;
bool square[MAXN][MAXN];
bool vis[MAXN][MAXN];
int size;
int dir[8][2] = {{-1, 0},
                 {-1, 1},
                 {-1, -1},
                 {0,  1},
                 {0,  -1},
                 {1,  0},
                 {1,  1},
                 {1,  -1}};

void dfs(int x, int y, int depth) {
    if (x < 0 || y < 0 || x >= n || y >= m) return;
    if (vis[x][y] || !square[x][y]) return;
    vis[x][y] = true;
    size++;
    maxSize = max(size, maxSize);
    for (int i = 0; i < 8; i++) {
        dfs(x + dir[i][0], y + dir[i][1], depth + 1);
    }
}

int main() {
    while (~scanf("%d,%d", &n, &m)) {
        CLEAR(vis, 0);
        maxSize = 0;
        for (int i = 0; i < n; i++) {
            char line[MAXN << 1];
            scanf("%s", line);
            for (int j = 0; line[j]; j++) {
                if (line[j] == ',') continue;
                if (line[j] == '0') {
                    square[i][j >> 1] = false;
                } else {
                    square[i][j >> 1] = true;
                }
            }
        }
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (!vis[i][j] && square[i][j]) {
                    size = 0;
                    cnt++;
                    dfs(i, j, size);
                }
            }
        }
        cout << cnt << ',' << maxSize << endl;
    }
    return 0;
}

第二题

题面【区间合并问题,不知道为什么只通过20%】:

有多个不同区间,区间之间可能存在重叠,求出合并后的区间断。
输入一个整数m,代表有m行输入区间,每行包括数量不定的区间

这题得处理输入数据,因此用Python写更方便一点

输入:
3
1,10;32,45
78,94;5,16
80,100;200,220;16,32
输出:
1,45;78,100;200,220
代码:
# coding=utf-8
import sys

if __name__ == "__main__":
    m = int(sys.stdin.readline().strip())
    if m < 1:
        print(None)
    else:
        result = []
        for i in range(m):
            line = sys.stdin.readline().strip().split(';')
            for query in line:
                tmp = query.split(',')
                min_v = min(int(tmp[0]), int(tmp[1]))
                max_v = max(int(tmp[0]), int(tmp[1]))
                result.append((min_v, max_v))
        result.sort()
        # print(result)
        merge = []
        current = [result[0][0], result[0][1]]
        for i in range(1, len(result)):
            if current[0] <= result[i][0] <= current[1]:
                if result[i][1] > current[1]:
                    current[1] = result[i][1]
            else:
                merge.append((current[0], current[1]))
                current[0] = result[i][0]
                current[1] = result[i][1]
        merge.append((current[0], current[1]))
        print(merge)

第三题

应该是背包问题

第四题

不太会

第五题

题面【贪心活动安排问题】:
  • 输入一个n,代表有几个直播节目;
  • 输入一个m,代表每天有几个小时;【即现在每天不是24小时,而是m小时】
  • 输入每个直播的起始时间、结束时间;
有两点注意事项
  1. 首先要对数据中主播开始时间大于结束时间的数据进行处理(即处理跨天数据),将跨天数据的结束时间加上m;
  2. 注意题目中描述的“一天”时间的范围,是从选择的第一个活动的起始时间算起,比如第一个直播开始时间是3点,则题目中的一天指的是今天3点到明天3点,而不是今天0点到明天0点;
输入:
3
10
0 3 3 7 7 0
输出:
3
代码:
#include 
#include 

using namespace std;

struct activity {
    int si, ti;
} record[100001];

bool cmp(activity a, activity b) {
    return a.ti < b.ti;
}

int main() {
    int m, n;
    while (cin >> n >> m) {
        if (n < 1 || m < 2)
            cout << 0 << endl;
        else {
            for (int i = 0; i < n; ++i) {
                cin >> record[i].si >> record[i].ti;
                if (record[i].si > record[i].ti)
                    record[i].ti += m;
            }
            sort(record, record + n, cmp);
            int count = 1;
            int last = 0;
            int limit = record[last].si + m;
            for (int i = 1; i < n; i++) {
                if (record[i].si >= record[last].ti && record[i].ti <= limit) {
                    last = i;
                    count++;
                }
            }
            cout << count << endl;
        }
    }
    return 0;
}

你可能感兴趣的:(今日头条笔试题)