大家可能也发现我是实时更新的,所以大家可以点赞、评论,如果讲解的不够详细或者看不懂的都可以留言。多给我些反馈,可以让我更好的编写博客内容。(但是别催更啊~~)
题目描述
一个4×4的矩阵,我们可以把矩阵看成内外两圈,我们可以把外圈按顺时钟或者逆时钟转动,每次转动一个格子。 我们想得到一个2×2的子矩阵,使得这个子矩阵4个元素的累加和最大。请问最大子矩阵的元素累加和是多少?
输入
第一行是一个整数T(1≤T≤1000),表示样例的个数。 每个样例占4行,每行4个整数,所有元素在[1,1000]范围内。
输出
每行输出一个样例的结果。
样例输入
2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 1 2 2 3 3 4 4 2 2 1 1 4 4 3 3样例输出
56 15提示
第一个样例,逆时钟旋转1格,得到最大子矩阵为
11 16 14 15
第二个样例,逆时钟旋转5格,得到最大子矩阵为3 4 4 4
解题思路:本题最大的 2 * 2矩阵 就三种情况。 1: 内圈四元素、2: 内圈1元素+外圈3元素、 3: 内圈2元素+外圈2元素。 这题的两种方法,一种就是纯粹的用二维数组,然后一次一次的转动外圈,暴力求解 ,另一种就是把二维数组数据转化为一维数组,把外圈和内圈的数分别存在一个一维数组中,过程可能有些绕,但是解题思路还是很明确的。
这里我用的是第二种方法:代码写的有些绕,就不写详细的题解了,直接对着代码讲解。
maxiner == 内圈四个元素之和,in1 == 内圈四个元素中最大值,in2 == 内圈四个元素中两最大相邻数之和,out2 == 外圈十二个元素中两最大相邻数之和, out3 == 外圈十二个元素中三最大相邻数之和。
scanF() 输入函数之后,就把 外圈内圈元素都存在了一维数组中, 在comput()中 有个 取模的运算,这使一维数组转化成一个圈,实现了轮转的功能(到数组末尾后又跳转到数组开头)。
43行交换函数,把inter[2] 和 inter[3] 交换位置,是因为我用for循环直接输入,存入内圈数组的 第二个数就和第三个数相邻了。但实际上不是,第二是和第四相邻,第一和第三相邻的。(能否理解)
其他的应该看代码上的注释可以看懂,如有疑惑的请留言。
AC代码:
#include <stdio.h>
int outer[15],inter[5];
int left,right,ins,ans;
int T,maxiner,in1,in2,out2,out3;
void Swap(int &x,int &y){ // 交换函数,就为了换一次,小题大做了,但还是手痒
int t;
t = x, x = y, y = t;
}
int Max(int x,int y,int z) // 比较函数,返回(x,y,z)中的最大值
{
if (x >= y && x >= z) return x;
if (y >= x && y >= z) return y;
if (z >= x && z >= y) return z;
return 0;
}
void scanF()
{
left = 6,right = 5,ins = -1;
maxiner = in1 = in2 = out2 = out3 = 0;
for (int i = 1; i <= 4; i ++) // 输入第一行
scanf("%d",&outer[++right]);
for (int i = 1; i <= 2; i ++) // 输入第二三行
{
scanf("%d",&outer[--left]);
for (int j = 1; j <= 2; j ++) // 注意这里直接输入有误,还需处理(43行)
{
scanf("%d",&inter[++ins]);
maxiner += inter[ins]; // 内圈 2*2 元素和
if (inter[ins] > in1) in1 = inter[ins]; // 内圈最大值
}
scanf("%d",&outer[++right]);
}
for (int i = 1; i <= 4; i ++) // 输入第四行
scanf("%d",&outer[--left]);
}
void comput()
{
Swap(inter[2],inter[3]);
for (int i = 0; i < 4; i ++)
{
int t1 = inter[i]+inter[(i+1)%4];
if (t1 > in2) in2 = t1; // 内圈最大的两个相邻元素和
}
for (int i = 0; i < 12; i ++)
{
int t2 = outer[i] + outer[(i+1)%12];
int t3 = t2 + outer[(i+2)%12];
if (t2 > out2) out2 = t2; // 外圈最大的两个相邻元素和
if (t3 > out3) out3 = t3; // 外圈最大的三个相邻元素和
}
}
int main()
{
scanf("%d",&T);
while ( T --)
{
scanF();
comput();
ans = Max(maxiner,in1+out3,in2+out2);
printf("%d\n",ans);
}
return 0;
}