莫大侠练成纵横剑法,走上了杀怪路,每次仅出一招。这次,他遇到了一个正方形区域,由n×n个格子构成,每个格子(行号、列号都从1开始编号)中有若干个怪。莫大侠施展幻影步,抢占了一个格子,使出绝招“横扫四方”,就把他上、下、左、右四个直线方向区域内的怪都灭了(包括抢占点的怪)。请帮他算算他抢占哪个位置使出绝招“横扫四方”能杀掉最多的怪。如果有多个位置都能杀最多的怪,优先选择按行优先最靠前的位置。例如样例中位置(1,2)、(1,3),(3,2),(3,3)都能杀5个怪,则优先选择位置(1,2)。
输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。对于每组测试,第一行输入n(3≤n≤20),第二行开始的n行输入n×n个格子中的怪数(非负整数)。
输出格式:
对于每组测试数据输出一行,包含三个整数,分别表示莫大侠抢占点的行号和列号及所杀的最大怪数,数据之间留一个空格。
输入样例:
2
3
1 1 1
0 1 1
1 1 1
3
3 2 1
4 6 5
8 7 9
输出样例:
1 2 5
3 2 32
代码实现1:
import numpy as np
T = int(input())
for i in range(T):
flag = 0
n = int(input())
arr = []
rowcnt = []
colcnt = []
res = np.random.randint(0, 1, size=n*n)
res = res.reshape((n,n))
for j in range(n):
mylist = list(map(int, input().split()))
arr.append(mylist)
rowcnt.append(sum(mylist))
for k in range(n):
colcnt.append(sum(row[k] for row in arr))
for x in range(n):
for y in range(n):
res[x][y] = rowcnt[x] + colcnt[y] -arr[x][y]
maxval = np.max(res)
m = np.argmax(res) # 把矩阵拉成一维,m是在一维数组中最大值的下标
r, c = divmod(m, res.shape[1]) # r和c分别为商和余数,即最大值在矩阵中的行和列
print(r+1, c+1, maxval)
写完快快乐乐地交上去,结果发现不能用numpy。无奈之下,有了第二种实现。其实第二种实现思路更传统,反倒看起来更简洁。
方法1在最终输出最大元素的位置的部分参考了python - 使用numpy寻找【二维数组】中的最值及其下标_个人文章 - SegmentFault 思否 这篇文章的做法。
代码实现2:
T = int(input())
for i in range(T):
flag = 0
n = int(input())
arr = []
rowcnt = []
colcnt = []
for j in range(n):
mylist = list(map(int, input().split()))
arr.append(mylist)
rowcnt.append(sum(mylist))
for k in range(n):
colcnt.append(sum(row[k] for row in arr))
r, c = 0, 0
maxval = arr[r][c]
for x in range(n):
for y in range(n):
arr[x][y] = rowcnt[x] + colcnt[y] -arr[x][y]
if(arr[x][y] > maxval):
r, c = x, y
maxval = arr[x][y]
print(r+1, c+1, maxval)
思路:
统计每行总数、每列总数,分别存储到列表中。
遍历原始二维数组,每个位置上能干掉的怪的数量=该行和+该列和-该格和。