您的位置:首页 > 其它

《算法竞赛-训练指南》第一章-1.24-UVa 10755

2013-08-03 19:43 281 查看
泪奔了哇,今天就搞了这一道题目,最后这道题目是三维的最大矩阵和的题目。

题目描述看了很久都没看懂,还是看了题解。

想说说这种题目,核心的思想还是降维,贪心求解,降维就意味着你要固定除了遍历的其他维,这道题目,要遍历z所以要固定其他的两维x,y,然后就是利用贪心的做法,把所有的和都求出来,然后保留最小的和,需要注意的一点的是,你的那个最小的和,一定要在每次换固定维的时候即使更新,要不然就会出错,在这上面我犯了几次错误。

还有一些作者的牛之处,我就不多说了,真的狠佩服作者灵光的大脑。

贴出代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

const int MAXN = 30;

const int long long INF = 1LL << 60;

long long S[MAXN][MAXN][MAXN];

void expand(int i, int &a0, int &b0, int &c0)
{
a0 = i & 1;
i >>= 1;
b0 = i & 1;
i >>= 1;
c0 = i & 1;
}

int sign(int a, int b, int c)
{
return (a + b + c) % 2 == 0 ? -1 : 1;
}

long long getSum(int x1, int x2, int y1, int y2, int z1, int z2)
{
int dx = x2 - x1 + 1;
int dy = y2 - y1 + 1;
int dz = z2 - z1 + 1;
long long s = 0;
for (int i = 0; i < 8; i++)
{
int a0, b0, c0;
expand(i, a0, b0, c0);
s -= S[x2 - a0 * dx][y2 - b0 * dy][z2 - c0 * dz] * sign(a0, b0, c0);
}
return s;
}

int main()
{
int T;
int A, B, C;
scanf("%d", &T);
while (T--)
{
scanf("%d%d%d", &A, &B, &C);
for (int i = 1; i <= A; i++)
{
for (int j = 1; j <= B; j++)
{
for (int k = 1; k <= C; k++)
{
scanf("%lld", &S[i][j][k]);
}
}
}
for (int i = 1; i <= A; i++)
{
for (int j = 1; j <= B; j++)
{
for (int k = 1; k <= C; k++)
{
for (int t = 1; t <= 7; t++)
{
int a0, b0, c0;
expand(t, a0, b0, c0);
S[i][j][k] += S[i - a0][j - b0][k - c0] * sign(a0, b0, c0);
}
}
}
}
long long ans = -INF;
for (int x1 = 1; x1 <= A; x1++)
{
for (int x2 = x1; x2 <= A; x2++)
{
for (int y1 = 1; y1 <= B; y1++)
{
for (int y2 = y1; y2 <= B; y2++)
{
long long MIN = 0; //总是弄错这里....
for (int z = 1; z <= C; z++)
{
long long sum = getSum(x1, x2, y1, y2, 1, z);
ans = max(ans, sum - MIN);
MIN = min(MIN, sum);
}
}
}
}
}
printf("%lld\n", ans);
if (T)
{
printf("\n");
}
}
// system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: