7-2 纵横

莫大侠练成纵横剑法,走上了杀怪路,每次仅出一招。这次,他遇到了一个正方形区域,由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)


思路: 

统计每行总数、每列总数,分别存储到列表中。

遍历原始二维数组,每个位置上能干掉的怪的数量=该行和+该列和-该格和。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值