二维数组区块计数
题目描述
输入一个只包含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日)