Nowcoder/ByteCamp 20190525

二维数组区块计数

题目描述

输入一个只包含0和1的二维数组。上下左右和对角相邻的1组成一个区块,0不形成区块。求数组中区块的个数。

  • 输入描述
第一行输入为两个正整数N和M,N表示数组行数,M表示数组列数。
之后N行每行表示数组对应的一行,每行有M个整数,整数之间用空格分开。
0 <= N <= 1000000, 0 <= M <= 1000000, N X M <= 1000000。
  • 输出描述
对于每个数组输出一个整数表示区块个数,行首行末均无多余空格。
  • 示例1

    • 输入
    3 3
    0 1 0
    1 0 0
    1 0 1
    
    • 输出
    2
    
    • 说明
    除了右下角的1单独形成1个区块之外,其他的1对角或上下对邻形成1个区块。
    

双端队列、栈、标记位

import sys
from collections import deque


def area_count(row, col, seq):
    num_one_stack = deque()
    for ru in range(row):
        for cu in range(col):
            if seq[ru][cu] == 1:
                num_one_stack.append((ru, cu))

    area_num = 0
    while num_one_stack:
        current = [num_one_stack.popleft()]
        while current:
            r, c = current[-1]
            exist_flag = False
            for i in range(r-1, r+2):
                for j in range(c-1, c+2):
                    if (r, c) != (i, j) and (i, j) in num_one_stack:
                        num_one_stack.remove((i, j))
                        current.append((i, j))
                        exist_flag = True
            if not exist_flag:
                current.pop()
        area_num += 1

    return area_num


if __name__ == '__main__':
    row, col = None, None
    for line in sys.stdin:
        row, col = map(int, line.strip().split(' '))
        break

    seq, count = [], 0
    for line in sys.stdin:
        seq.append(list(map(int, line.strip().split(' '))))
        count += 1
        if count == row:
            break

    if row and col and seq:
        print(area_count(row, col, seq))
    else:
        print(0)

国庆旅行

题目描述

小明国庆节来北京玩,北京有N个景点,第i个景点的评分用a[i]表示,两个景点i, j之间的距离为j-i(j>i),小明一天只能游玩两个景点,我们认为总评分是两个景点的评分减去距离,即为a[i]+a[j]+i-j,那么小明选择哪两个景点才会总评分最大呢?

  • 输入描述
第一行输入N(2 <= N <= 100000)
第二行分别输入N个景点的评分(1 <= a[i] <= 1000)
  • 输出描述
输出最大评分
  • 示例1

    • 输入
    5
    11 6 5 18 12
    
    • 输出
    29
    

动态规划

import sys


def attraction_rate(length, seq):
    start, end = 0, 1
    value_start, value_end = seq[start], seq[end]
    idx = end + 1
    max_rate = value_end + value_start - 1
    while idx < length:
        cur = seq[idx]

        cur_one_start = cur + value_start + start - idx
        cur_one_end = cur + value_end + end - idx
        if cur_one_start > cur_one_end and cur_one_start > max_rate:
            max_rate = cur_one_start
            end, value_end = idx, cur
        elif cur_one_end > max_rate and cur_one_end > max_rate:
            max_rate = cur_one_end
            start, end = end, idx
            value_start, value_end = value_end, cur

        cur_two = cur + seq[idx-1] - 1
        if cur_two > max_rate:
            max_rate = cur_two
            start, end = idx - 1, idx
            value_start, value_end = seq[idx-1], cur

        idx += 1

    return max_rate


if __name__ == '__main__':
    length = None
    for line in sys.stdin:
        length = list(map(int, line.strip().split(' ')))[0]
        break

    seq = []
    for line in sys.stdin:
        seq = list(map(int, line.strip(). split(' ')))
        break

    if length and seq:
        print(attraction_rate(length, seq))

字符串展开

题目描述

小赵和小钱在练字,小钱对小赵说:你知道吗,我练习的字是有蕴含的。小赵不服气了,凭什么你的就有蕴含呢?小钱说,你所看到的并不是我真正练习的字,你需要将我现在写下的字符串里的"%“和”#"之间的字重复符号前的那么多倍,才能看到我真正写的是什么!你能帮帮小赵吗?

说明:可能存在嵌套的情况,如"3%g2%n##",返回"gnngnngnn"。输入和输出字符串长度均不超过10000。

  • 输入描述
一行带数字和嵌套符号的字符串
  • 输出描述
展开的字符串
  • 示例1

    • 输入
    3%acm#2%acm#
    
    • 输出
    acmacmacmacmacm
    

标记位

import sys


def string_expand(code_string):
    container, res = [], ''
    current, count = '', ''
    start, end = False, False
    for su in code_string:
        if not start:
            if su.isdigit():
                count += su
            elif su == '%':
                start, end = True, False
            elif su == '#':
                num, value = container.pop()
                res = num * (value + res)
        else:
            if su.isalpha():
                current += su
            elif su.isdigit():
                container.append((int(count), current))
                current, count = '', su
                start = False
            elif su == '#':
                if not end:
                    res += int(count) * current
                    start, end = False, True
                    current, count = '', ''
                else:
                    num, value = container.pop()
                    res = num * (value + res)
    return res


if __name__ == '__main__':
    original_string = None
    for line in sys.stdin:
        original_string = line.strip()
        break

    # 2%c2%b#3%a1%d###
    print(string_expand(original_string))

最短移动距离

题目描述

给定一颗n个节点树。节点1为树的根节点,对于所有其他节点i,它们的父节点编码为floor(i/2)(i除以2的整数部分)。在每个节点i上有a[i]个房间。此外树上所有边均是边长为1的无向边。

树上一共有m只松鼠,第j只松鼠的初始位置为b[j],它们需要通过树边各自找到一个独立的房价。请为所有松鼠规划一个移动方案,使得所有松鼠的总移动距离最短。

  • 输入描述
输入共有三行。
第一行包含两个正整数n和m,表示树的节点数和松鼠的个数。
第二行包含n个自然数,其中第i个数表示节点i的房间数a[i]。
第三行包含m个自然数,其中第j个数表示松鼠j的初始位置b[j]。
  • 输出描述
输出一个数,表示m只松鼠各自找到独立房间的最短移动距离。
  • 示例1

    • 输入
    5 4
    0 0 4 1 1
    5 4 2 2
    
    • 输出
    4
    
    • 说明
    前两只松鼠不需要移动,后两只松鼠需要经节点1移动到节点3。
    

待续


(最近更新:2019年06月16日)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值