ACM模式与核心代码模式

文章目录

  • ACM模式
    • 输入函数模板(Python)
      • 获取输入数据
      • 三种情况的输入数据
    • 输出函数模板
    • 链表的输入输出
    • 二叉树
      • 二叉树的输入输出
  • 核心代码模式
  • 参考文献

蓝桥杯解决算法问题采用的ACM模式。我们平时所用的刷题网站主要分为ACM模式,和核心代码模式,下面阐述一下ACM模式与核心代码模式的区别。

ACM模式

ACM模式就是需要自己输入数据的格式,将数据填充到需要处理的容器中,OJ系统不提供任何代码,包括include头文件,导入第三方库import,都需要自己填写。最后还需要自己控制返回的数据格式。国内采用ACM模式的网站有牛客网。

输入函数模板(Python)

获取输入数据

python主要通过input()函数实现数据的输入,input()会读取控制台的一行输入,如果输入多行则需要使用多个input()。

# 输入为: 1 2 3 4 5
a = input()
# a = '1 2 3 4 5'

注意在python3中,input()函数会将输入数据返回为一个string类型。如果一行中有多个数据,我们可以使用split()将其进行切割,split()切割后返回一个列表

# 输入为: 1 2 3 4 5
a = input().split() # split()默认以空字符为分隔符,包括空格、换行(\n)、制表符(\t)等
# a = ['1', '2', '3', '4', '5']
	  
# 输入为:1,2,3,4,5
b = input().split(',') # 以逗号为分隔符
# b = ['1', '2', '3', '4', '5']

我们知道input()返回的是一个string类型,所以通过split()分割后得到的是一个字符列表。如果输入数据是数字则需要进行类型转换。常见的转换方式有一下几种:

  • 单个数据转换;
  • 列表批量转换;
  • 使用map()并且转换,map()函数返回的是一个迭代器,不能赋值也不能索引,如果需要改变值的话我们需要将其转化为列表。
# 输入为: 1 
a = int(input()) # 单个转换
	  
# 输入为:1 2 3 4 5
b = input().split() # b = ['1', '2', '3', '4', '5']
c = [int(i) for i in b] # 使用列表进行批量转换 c = [1, 2, 3, 4, 5]
d = [int(i) for i in input().split()] # 当然可以一步倒位
	  
# 使用map进行并行转换
e = map(int, input().split()) # 此时e是一个map迭代器,不能赋值,也不能索引
f = list(e) # 转换为列表,e = [1, 2, 3, 4, 5]
g = list(map(int, input().split())) # 一步到位  

三种情况的输入数据

1.多行输入同时未指定输入用例的个数

while True:
	  try:
	      data = input()
	      solve(data) # 核心函数
	  except:
	      break

2.多行输入,指定输入用例的个数

n = int(input()) 获取用例个数
for _ in range(n):
	  data = input()
	  solve(data) # 核心函数

3.多行输入,指定某个条件退出

while True:
	  data = input()
	  if judge(data): # 判断
	      break
	  solve(data)

输出函数模板

python3的输出主要通过print()函数实现,把结果打印至终端。
关于print()函数。

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
  • objects – 复数,表示可以一次输出多个对象。输出多个对象时,需要用分隔符分开,默认为空格。
  • sep – 用来间隔多个对象,默认值是一个空格
  • end – 用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符串
  • file – 要写入的文件对象。
  • flush – 输出是否被缓存通常决定于 file,但如果 flush 关键字参数为 True,流会被强制刷新。
    输出函数模板一般有三种情况:
    情况一:输出单个数字
# 输出 a (a = 1)
print(a)

情况二:输出多个数字,同时要求以分隔符分开

# 输出 a=1, b=2, c=3
print(a, b, c) # print默认以空格为分隔符
# output:1 2 3
print(a, b, c, sep=',') # 以逗号为分隔符
# output:1,2,3

情况三:最终结果为一个列表

# 最终结果 res = [1, 2, 3]
# 1. 直接输出列表
print(res)
# 2. 输出列表, 每个元素单独输出
for i in range(len(res)):
    print(res[i])
#output: 1
#        2
#        3

# 3. 输出列表,每个元素单独输出,同时还需要在同一行输出, 以空格分隔
for i in range(len(res)):
    print(res[i], end=' ')  # end的默认值是'\n',即换行
    # output: 1 2 3 

情况四:将字符列表合成一个字符串,需要用到join()函数
在 Python 中,join() 是字符串对象的一个方法,用于将序列(通常是列表或元组)中的元素连接成一个字符串。

# res = ['a', 'b', 'c']
# 输出是一个字符串
print("".join(res))
# output: abc

# 输出是一个字符串,且用 * 号分隔
print("*".join(res))
# output: a*b*c
# 如果用 print(res[i], end = '*') 的话,输出就是 a*b*c*了,在末尾还多了一个*

链表的输入输出

ACM模式中链表是通过一个一个数组来模拟的,所以获取输入数据与前面一样。主要的区别在于定义链表结构,将输入数据转换为链表和输出链表

# 定义链表结构
class ListNode:
    def __init__(self,val,next=None):
        self.val = val
        self.next = next

# 数组转链表
def nums2ListNode(nums):
    dummy = ListNode(None)
    root = ListNode(nums[0])
    dummy.next = root
    i = 1
    while i < len(nums):
        node = ListNode(nums[i])
        root.next = node
        root = root.next
        i += 1
        root.next = None
    return dummy.next

# 打印链表
nums = [1,2,3,4,5]
root = nums2ListNode(nums)
while root:
    print(root.val)
    root = root.next

二叉树

二叉树的输入输出

完全二叉树的格式输入
ACM模式中,一般用输入一行数字代表二叉树,一般会以完全二叉树格式输入。这行数字的按照层序遍历的顺序排列,且其中空节点一般会用特定的符号表示,如0或是null。
可以直接用数组表示二叉树,例如列表Tree, 将Tree[i]的左子树和右子树分别为Tree[2i+1]和Tree[2i+2],不过会比较占用空间。

# 中序遍历
def inorder_traversal(nums, index):
    if index >= len(nums) or nums[index] == -1:
        return
    left, right = 2 * index + 1, 2 * index + 2
    inorder_traversal(nums, left)
    print(nums[index], end = ' ')
    inorder_traversal(nums, right)
	  
	  
# 输入为 1 2 3 null 4 null 5
#      1
#    /   \
#   2     3
#    \     \
#     4     5
if __name__ == "__main__":
    nums = input().split()
    nums = [int(num) if num != 'null' else -1 for num in nums]
    inorder_traversal(nums, 0)

    # output: 2 4 1 3 5 

也可以用链表实现二叉树,更省空间,但操作更复杂一些。

# 定义二叉树类函数
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
	  
	  
# 由数组转二叉树
def construct_binary_tree(nums, index):
    if index >= len(nums):
        return
    # -1作为空节点
    if nums[index] == -1:
        return None
    left = index * 2 + 1
    right = index * 2 + 2
    root = TreeNode(nums[index])
    root.left = construct_binary_tree(nums, left)
    root.right = construct_binary_tree(nums, right)
    return root

# 中序遍历
def inorder_traversal(root):
    if not root: return
    inorder_traversal(root.left)
    print(root.val, end=' ')
    inorder_traversal(root.right)

# 输入为 1 2 3 null 4 null 5
#      1
#    /   \
#   2     3
#    \     \
#     4     5
if __name__ == "__main__":
	nums = input().split()
	nums = [int(num) if num != 'null' else -1 for num in nums]
	root = construct_binary_tree(nums, 0)
	inorder_traversal(root)
   # output: 2 4 1 3 5  

核心代码模式

核心代码模式就是你只需要写解决问题的逻辑,即解决问题的函数。不需要自己写输入输出代码。OJ系统已经将需要处理的数据放到容器中了。采用核心代码的刷题网站有力扣。

参考文献

博客1
博客2

你可能感兴趣的:(蓝桥杯备赛(Python组),算法,蓝桥杯,python)