ACM模式与核心代码模式

蓝桥杯解决算法问题采用的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

  • 45
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
1 图论 3 1.1 术语 3 1.2 独立集、覆盖集、支配集之间关系 3 1.3 DFS 4 1.3.1 割顶 6 1.3.2 桥 7 1.3.3 强连通分量 7 1.4 最小点基 7 1.5 拓扑排序 7 1.6 欧拉路 8 1.7 哈密顿路(正确?) 9 1.8 Bellman-ford 9 1.9 差分约束系统(用bellman-ford解) 10 1.10 dag最短路径 10 1.11 二分图匹配 11 1.11.1 匈牙利算法 11 1.11.2 KM算法 12 1.12 网络流 15 1.12.1 最大流 15 1.12.2 上下界的网络的最大流 17 1.12.3 上下界的网络的最小流 17 1.12.4 最小费用最大流 18 1.12.5 上下界的网络的最小费用最小流 21 2 数论 21 2.1 最大公约数gcd 21 2.2 最小公倍数lcm 22 2.3 快速幂取模B^LmodP(O(logb)) 22 2.4 Fermat小定理 22 2.5 Rabin-Miller伪素数测试 22 2.6 Pollard-rho 22 2.7 扩展欧几里德算法extended-gcd 24 2.8 欧拉定理 24 2.9 线性同余方程ax≡b(mod n) 24 2.10 中国剩余定理 25 2.11 Discrete Logging(BL == N (mod P)) 26 2.12 N!最后一个不为0的数字 27 2.13 2^14以内的素数 27 3 数据结构 31 3.1 堆(最小堆) 31 3.1.1 删除最小值元素: 31 3.1.2 插入元素和向上调整: 32 3.1.3 堆的建立 32 3.2 并查集 32 3.3 树状数组 33 3.3.1 LOWBIT 33 3.3.2 修改a[p] 33 3.3.3 前缀和A[1]+…+A[p] 34 3.3.4 一个二维树状数组的程序 34 3.4 线段树 35 3.5 字符串 38 3.5.1 字符串哈希 38 3.5.2 KMP算法 40 4 计算几何 41 4.1 直线交点 41 4.2 判断线段相交 41 4.3 三点外接圆圆心 42 4.4 判断点在多边形内 43 4.5 两圆交面积 43 4.6 最小包围圆 44 4.7 经纬度坐标 46 4.8 凸包 46 5 Problem 48 5.1 RMQ-LCA 48 5.1.1 Range Minimum Query(RMQ) 49 5.1.2 Lowest Common Ancestor (LCA) 53 5.1.3 Reduction from LCA to RMQ 56 5.1.4 From RMQ to LCA 57 5.1.5 An algorithm for the restricted RMQ 60 5.1.6 An AC programme 61 5.2 最长公共子序列LCS 64 5.3 最长上升子序列/最长不下降子序列(LIS) 65 5.3.1 O(n^2) 65 5.3.2 O(nlogn) 66 5.4 Joseph问题 67 5.5 0/1背包问题 68 6 组合数学相关 69 6.1 The Number of the Same BST 69 6.2 排列生成 71 6.3 逆序 72 6.3.1 归并排序求逆序 72 7 数值分析 72 7.1 二分法 72 7.2 迭代法(x=f(x)) 73 7.3 牛顿迭代 74 7.4 数值积分 74 7.5 高斯消元 75 8 其它 77

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好好学习、天天向上。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值