问题描述
Petya是Berland公司BerSoft的公关经理,他需要制作一份关于公司自2001年以来收入增长的报告。在报告中,Petya想展示一个"完美"的线性增长模式,即每年收入比前一年增长1个亿。例如,2001年收入为1亿,2002年为2亿,以此类推。
但由于真实收入数据与完美模式有所差异,Petya决定忽略一些数据,保留一个收入增长符合完美模式的最长子序列。具体要求如下:
- 给定一个包含公司各年收入的序列,Petya需要选择一个最长的子序列,使得该子序列的收入序列为:1, 2, 3, 4, ...,即收入逐年增加1亿。
- 如果这样的子序列存在,输出其长度及对应的年份;否则输出0。
输入
- 第一行:一个整数n (1 ≤ n ≤ 100),表示年份的数量。
- 第二行:n个整数a1, a2, ..., an (-100 ≤ ai ≤ 100),表示每年公司的收入(单位:亿)。
输出
- 输出一个整数k,表示最长的完美增长序列的长度。
- 输出k个整数,表示这些年份对应的收入符合完美增长序列的年份。如果不存在这样的子序列,输出0。
解题思路
我们的问题本质上是从给定的收入序列中找到一个满足条件的最长子序列,使得该子序列的值依次为1、2、3、4......,即收入逐年递增。
为了实现这一点,我们可以采用贪心算法。贪心策略是:从头到尾遍历收入序列,尽量选择最小的符合条件的收入来构建最长的完美增长子序列。
步骤分析
- 输入解析:我们首先读取年份数n和每年对应的收入数据。
- 贪心选择:从收入序列中查找是否能依次匹配1、2、3......等数值。如果匹配成功,则记录对应年份,并寻找下一个符合条件的收入。
- 输出:如果能找到符合条件的子序列,输出其长度及对应的年份;否则输出0。
具体实现
def main():
# 读取输入
n = int(input()) # 年份数量
incomes = list(map(int, input().split())) # 收入数据
target = 1 # 初始目标值为1
sequence = [] # 存储符合条件的年份序列
# 遍历收入数据
for i in range(n):
if incomes[i] == target: # 如果当前收入符合目标值
sequence.append(2000 + i + 1) # 记录该年(2000 + i + 1)
target += 1 # 目标值加1,查找下一个符合条件的收入
# 如果找到了符合条件的序列
if sequence:
print(len(sequence)) # 输出符合条件的子序列的长度
print(*sequence) # 输出符合条件的年份
else:
print(0) # 如果没有符合条件的序列,则输出0
if __name__ == "__main__":
main()
代码解析
-
输入读取:
- 使用
input()
函数读取年份数n
。 - 使用
map()
和split()
将收入数据转换为整数列表。
- 使用
-
贪心策略:
- 我们从目标值
1
开始,逐年查找是否存在对应收入。如果找到了1
,则找2
,依此类推。 - 如果当前收入匹配目标值,则将当前年份(即
2000 + i + 1
)加入结果列表。
- 我们从目标值
-
输出:
- 如果找到了符合条件的子序列,我们输出子序列的长度和年份。
- 如果没有找到符合条件的子序列,则输出
0
。
复杂度分析
-
时间复杂度 :由于我们只遍历一次收入列表,时间复杂度为
O(n)
,其中n
是收入数据的数量。由于n
的最大值为100,因此该算法效率足够高。 -
空间复杂度 :我们只使用了一个列表来存储符合条件的年份,因此空间复杂度为
O(n)
。
示例分析
示例1:
输入:
10
-2 1 1 3 2 3 4 -10 -2 5
- 我们的目标序列是
1, 2, 3, 4, 5, ...
。 - 在收入序列中,我们可以找到:
1
对应2002
年。2
对应2005
年。3
对应2006
年。4
对应2007
年。5
对应2010
年。
输出:
5
2002 2005 2006 2007 2010
示例2:
输入:
3
-1 -2 -3
- 由于没有正数,无法找到符合条件的增长序列。
输出:
0
总结
这道题目通过贪心策略和简单的遍历实现了查找符合完美增长条件的子序列。对于每个输入数据,我们尝试从收入序列中依次匹配目标值,直到没有更多符合条件的收入为止。通过这个方法,我们能够高效地找到最长的符合条件的子序列。