CCF-CSP 202206-2-寻宝大冒险 (Python) 三种思路 偏差列表,集合,元组 满分实现

202212-2-寻宝大冒险

问题

image-20230306012525827

image-20230305232838859

image-20230305234253304

思路

1、思路一

构建绿化图二维列表藏宝图二维列表,再以每棵树为原点构建不超出边界的局部二维列表,通过python的==,判断不超出边界的局部二维列表藏宝图二维列表是否相等。

2、思路二

思路一需要太多内存空间,为绿化图每个有树点(x0,y0),建立一个偏差列表,列表存(x0,y0)为原点,S为大小范围内有树点(xi,yi)-(x0,y0)的差值,即不超出边界的局部偏差列表藏宝图二维列表中检验

实现:

思路一——不超出边界的局部二维列表藏宝图二维列表是否相等
n, L, S = map(int, input().split()) # n棵树,L绿化图大小,S藏宝图大小
A = [[0 for _ in range(L+1)] for _ in range(L+1)] # A绿化图坐标
t = [] # 树的坐标列表
for _ in range(n): # 把n棵树写到A绿化图中
  x, y = map(int, input().split()) # 每棵树的坐标
  t.append([x,y])
  A[x][y] = 1
B = [[0 for _ in range(S+1)] for _ in range(S+1)] # B藏宝图坐标
for i in range(S,0-1,-1): # 把局部树写到B藏宝图中
  B[i] = list(map(int, input().split()))

res = 0 # 可能情况的数量
for i in t:
  if i[0] + S <= L and i[1] + S <= L:
    T = [] # 同大小局部绿化图坐标
    for j in range(S+1):
      T.append(A[i[0]+j][i[1]:i[1]+S+1])
    if T == B:
      res = res + 1
print(res)

image-20230306003438242

不该用来存地图

转换思路:

  1. 为绿化图每个有树点(x0,y0),建立一个列表
  2. 列表存(x0,y0)为原点,S为大小范围内有树点(xi,yi)-(x0,y0)的差值
思路二——不超出边界的局部偏差列表藏宝图二维列表中检验
n, L, S = map(int, input().split()) # n棵树,L绿化图大小,S藏宝图大小
points = [[i for i in map(int, input().split())] for _ in range(n)]
B = [[0 for _ in range(S+1)] for _ in range(S+1)] # B藏宝图坐标
for i in range(S,0-1,-1): # 把局部树写到B藏宝图中
  B[i] = list(map(int, input().split()))

bN = 0
for i in range(S+1):
  bN += len([i for i in B[i] if i == 1])

res = 0 # 可能情况的数量
for x0,y0 in points:
  if x0 + S <= L and y0 + S <= L:
    T = [] # 存储偏差列表
    for xi,yi in points:
      x = xi - x0
      y = yi - y0
      if 0 <= x <= S and 0 <= y <= S:
        T.append([x,y])
    flag = 0
    if len(T) == bN:
      for i in T:
          if B[i[0]][i[1]] != 1:
            flag = 1
            break
      if flag == 0:
        res = res + 1
print(res)

image-20230306011715768

1、简化一

t = [] # 树的坐标列表
for _ in range(n): # 把n棵树写到A绿化图中
x, y = map(int, input().split()) # 每棵树的坐标
t.append([x,y])
t = [[i for i in map(int, input().split())] for _ in range(n)]

2、简化二

bN = 0
for i in range(S+1):
	for j in range(S+1):
		if B[i][j] == 1:
			bN += 1;
bN = 0
for i in range(S+1):
bN += len([i for i in B[i] if i == 1])

3、for i in t: 当t是坐标时,可这样简化:

for x, y in points:
思路三——藏宝图化为偏差列表,在树坐标集合set中检验
n, L, S = map(int, input().split()) # n棵树,L绿化图大小,S藏宝图大小
points = set()
for _ in range(n):
    points.add(tuple([i for i in map(int, input().split())]))
B = [[0 for _ in range(S+1)] for _ in range(S+1)] # B藏宝图坐标
for i in range(S,0-1,-1): # 把局部树写到B藏宝图中
  B[i] = list(map(int, input().split()))

# 构建藏宝图的偏差列表
bBias = []
for i in range(S+1):
  for j in range(S+1):
    if B[i][j] == 1 :
      bBias.append([i,j])

# 在树坐标集合set中检验
res = 0 # 可能情况的数量
for x,y in points: # 遍历每一棵树
  flag = 0
  # print(bBias)
  for i in range(0,S+1): # 树的横偏差
    for j in range(0,S+1): # 树的纵偏差
      if ([i,j]  in bBias and (x+i,y+j) not in points) or + \
      + ([i,j] not in bBias and (x+i,y+j) in points) or + \
      + ((x+i > L or y+j > L)): # 不可能的情况(在偏差列表不在集合,在集合不在偏差列表)
        flag = 1
        break
    if flag == 1:
      break
  if flag == 0:
    # print(x,y)
    res += 1
print(res)

image-20230306025656298

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值