1.插座
问题描述
小蓝有一个插板,形状用一个 n * m 的01矩阵表示,0 表示板面,1 表示插孔。
小蓝还有一个插头,形状用一个 r * c 的01矩阵表示,0 表示没有伸出的部分,1 表示伸出的部分。插头伸出的部分必须插在插孔里面。
为了安全,插头插到面板上不能有任何部分超过插板边界(包括没有伸出的部分)。
插头和插板都不能旋转,也不能翻转。请求出插头插入插板的合理位置。输入格式
输入的第一行包含两个整数 n, m。
接下来 n 行,每行一个长度为 m 的01串,表示插板的形状。
接下来一行包含两个整数 r, c。
接下来 r 行,每行一个长度为 c 的01串,表示插头的形状。输出格式
如果插头没办法安全插入插板中,输出“NO”。否则输出两个数 a, b,表示插头的第 1 行第 1 列对应插板的第 a 行第 b 列。如果有多种情况满足要求,输出 a 最小的方案,如果 a 最小的方案有多个,输出在 a 最小的前提下 b 最小的方案。
样例输入
3 4
0 1 1 0
0 0 0 0
0 0 0 0
3 3
0 0 0
0 1 0
0 0 0样例输出
NO
样例说明
在插头不超出范围的前提下无法插入。
样例输入
4 7
1 1 1 0 1 0 0
1 1 0 1 1 1 1
0 0 0 1 1 1 1
0 0 0 0 0 1 1
2 3
1 1 1
0 1 1样例输出
2 4
评测用例规模与约定
对于 50% 的评测用例,2 <= n, m, r, c <= 20。
对于所有评测用例,2 <= n, m, r, c <= 100。
解析:内线os:这道题对我这种菜鸡来说,做了很久,因为这道题对我来说比较难。前期做的我想崩溃 ,不是这错就是哪错,非常无语。好在在一位朋友的帮助下,终于克服了!!真的代码题目就得多练啊!!!
思路:就是一道模拟题,不过要注意许多细节,比如输出的是行和列,不是下标。还有就是规定插座的一个点去遍历插头,注意不要超出插座的范围。
代码附上:
import sys
def check(a, b, x, y, x1, y1, m, n): # 插板 插头 插板遍历的行和列 插头的行和列 插板的行和列
for h in range(0, x1):
for k in range(0, y1):
if 0 <= h + x < n and 0 <= k + y < m: # 不能超出插板范围
if b[h][k] == 0 and (a[h + x][k + y] == 1 or a[h + x][k + y] == 0): # 插头为0时 插板可以为1或0
continue
elif b[h][k] == 1 and a[h + x][k + y] == 1: # 插头为1时 插座必须为1
continue
else: # 不符合规定的对应点 直接返回
return False
else: # 如果在该插座点固定时 遍历范围 如超出直接返回
return False
return True
# 插座
temp = 0 # 检测插头与插座 是否有符合的位置
n, m = map(int, input().split()) # 插板的行 和 列
lis_ban = [] # 存储插板的数组
for i in range(n):
num = list(map(int, input().split())) # 每一行输入m列 数字
lis_ban.append(num)
# 插头
r, c = map(int, input().split()) # 插头的行 和 列
lis_tou = [] # 存储插头的数组
for i in range(r):
num1 = list(map(int, input().split())) # 每一行输入c列数字
lis_tou.append(num1)
if r > n or c > m: # 插头的行或列不能大于插板
print('NO')
else:
for i in range(n):
for w in range(m):
if check(lis_ban, lis_tou, i, w, r, c, m, n):
print(str(i + 1) + ' ' + str(w + 1)) # 打印出的是 插座的行和列 不是下标!!!!!!!
temp = 1
sys.exit() # 找到第一个符合的点位 就直接输出 因为找的是插座最小的行和列
pass
if temp == 0: # 如果不符合 则直接返回NO
print('NO')