【例1】
给出一个长度为n的数组a1、a2、…、an,请找出在所有连续区间中,区间和最大同时这个区间0的个数小于等于3个,输出这个区间和。
输入:第一行一个正整数n,表示数组长度,1 <= n <= 1000000。
第二行为n个正整数a1 a2 … an,其中-1e9 <= a1,a2,…,an <= 1e9
输出:一个整数
样例:
输入1: 5
1 2 3 4 5
输出1: 15
输入2: 6
15 0 0 0 0 20
输出2: 20
Python实现
n = int(input())
nums = []
for i in range(0,n):
nums.append(int(input()))
total = [0,0,0]
zero_pos = [-1,-1,-1]
zero_seq = 0
max_ = 0
for i in range(0,n):
if 0 == nums[i]:
if zero_seq < 2:
zero_seq += 1
else:
if sum(total) > max_:
max_ = sum(total)
temp = total[1:3]
temp.append(0)
total = temp
else:
total[zero_seq] += nums[i]
if sum(total) > max_:
max_ = sum(total)
print(max_)
Go实现
package main
import "fmt"
func main() {
var n int
fmt.Scanf("%d\n", &n)
nums := make([]int, n)
for i := 0; i < n; i++ {
fmt.Scanln(&nums[i])
}
total := []int{0, 0, 0}
zero_index := 0
max := 0
for i := 0; i < n; i++ {
if 0 == nums[i] {
if zero_index < 2 {
zero_index++
} else {
sum := total[0] + total[1] + total[2]
if sum > max {
max = sum
}
total = append(total[1:3], 0)
}
} else {
total[zero_index] += nums[i]
}
}
sum := total[0] + total[1] + total[2]
if sum > max {
max = sum
}
fmt.Println(max)
}
【例2】
给定一个n * m 矩阵 A,矩阵中每个位置 Aij 为一个 16 进制数。
寻找一条从左上角到右下角的路径,每次只能向右或者向下移动,使得路径上所有数字之积在16进制下的后缀0最少。
输入:
第一行: n, m (2 <= n, m <= 1000)
接下来 n 行, 每行 m 个16进制整数, 0 < Aij < 10^9
输出:
第一行:最少后缀0的个数 (10进制)
第二行:路径方案, 从左上角开始, > 代表向右移动,V 代表向下移动。如果有多种方案,输出字典序最小的方案。
样例输入:
3 3
3 2 8
c 8 8
2 a f
样例输出:
1
>>VV
实现
s = input().split()
n = int(s[0])
m = int(s[1])
import itertools
print
A = []
for i in range(0,n):
row = []
s = input().split()
for j in range(0,len(s)):
row.append(int(s[j], 16))
A.append(row)
comb_origin = []
for i in range(0,n+m-2):
comb_origin.append(i)
comb = list(itertools.combinations(comb_origin,m-1)) #右转
best_zeros_nums = -1
best_str = ""
for item in comb:
STR = ""
i = 0
j = 0
total = A[i][j]
for seq in range(0, n+m-2):
if seq in item:
STR += ">"
j += 1
else:
STR += 'V'
i += 1
total = total*A[i][j]
zeros_nums = 0
total_hex = str(hex(total))
for i in range(len(total_hex)-1, -1, -1):
if total_hex[i] == '0':
zeros_nums += 1
else:
break
if zeros_nums < best_zeros_nums or best_zeros_nums == -1:
best_zeros_nums = zeros_nums
best_str = STR
print(best_zeros_nums)
print(best_str)
点评
××input多个数字时,用 input().split()
××排列组合用库itertools.combinations(list, num)
××如果是要排列位置的话,小技巧是,list用一个顺序排列的数组 [0,1,2,3,4…] 这样最后得到的组合结果就是指位置了
××将字符串按照16进制格式转换为int是 int(str, 16)
××将整数转换为16进制字符串 str(hex(int))
××for 倒序循环 i in range(倒序起始点, 倒序终止点, -1) 其中,是开闭区间的,-1是步长
【例3】
给定n个整数组成的序列,现在要求将序列分割为m段,每段子序列中的数在原序列中连续排列。如何分割才能使这m段子序列的和的最大值达到最小?
输入
第一行输入一个整数t,代表有t组测试数据。
每组数据第一行为两个整数n,m分别代表序列的长度和最多可分的段数。
接下来一行包含n个整数表示序列。
0<=n<=50000 1<=m<=n,0<=ai<=2^30。
输出
输出一个整数表示和最大的一段的最小值。
t = int(input())
a = []
m = []
for i in range(0, t):
temp = input().split()
n = int(temp[0])
m_i = int(temp[1])
m.append(m_i)
temp = input().split()
a_i = []
for j in range(0,len(temp)):
a_i.append(int(temp[j]))
a.append(a_i)
for id in range(0, t):
a_i = a[id]
m_i = m[id]
n_i = len(a_i)
dp = [[0 for i in range(0,m_i)] for j in range(0,n_i)]
dp[0][0] = a_i[0]
for i in range(1,n_i):
dp[i][0] = dp[i-1][0] + a_i[i]
for j in range(1,m_i):
for i in range(0,n_i):
minv = -1
for k in range(0,i):
temp = max(dp[i][0]-dp[k][0], dp[k][j-1])
if minv == -1 or temp < minv:
minv = temp
dp[i][j] = minv
print(dp[n_i-1][m_i-1])