您的位置:首页 > 其它

zoj 3578 matrix

2012-03-07 17:22 274 查看
Matrix

Time Limit: 10 Seconds Memory Limit: 131072 KB

A N*M coordinate plane ((0, 0)~(n, m)). Initially the value of all N*M grids are 0.

An operation T(a, b, h, x, y) is defined as follow:

1. Select the maximum value in the matrix (x, y) ~ (x+a, y+b), suppose the maximum value is max

2. Change all the value in the matrix (x, y) ~ (x+a, y+b) into max+h

After C operations, please output the maximum value in the whole N*M coordinate.

Input

The input consists of several cases.

For each case, the first line consists of three positive integers N , M and C (N ≤ 1000, M ≤ 1000, C ≤ 1000). In the following C lines, each line consists of 5 non-negative number, ai, bi, hi,xi, yi (0
≤ hi ≤ 10000, 0 ≤ xi < n, 0 ≤ yi < m).

Output

For each case, output the maximum height.

Sample Input

3 2 2
2 1 9 1 1
1 1 2 2 1

Sample Output

11


偷他的

http://kb.cnblogs.com/a/2369088/

#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

//#undef _DEBUG

#ifdef _DEBUG
#define debug_printf(...) printf(__VA_ARGS__)
#else
#define debug_printf(...)
#endif

struct HistoryBlock
{
int a, b, x, y, h, H;

bool crossesOverWith (const HistoryBlock &hb)
{
if (x + a <= hb.x || hb.x + hb.a <= x) {
return false;
} else if (y + b <= hb.y || hb.y + hb.b <= y) {
return false;
} else {
return true;
}
}
};

const int MAXC = 1000;

int main (int argc, char **argv)
{
HistoryBlock hb[MAXC];
int c;
int m;
int n;

while (scanf ("%d%d%d", &m, &n, &c) != EOF) {

for (int i=0; i<c; ++i) {

scanf ("%d%d%d%d%d", &hb[i].a, &hb[i].b, &hb[i].h, &hb[i].x, &hb[i].y);
hb[i].H = 0;

for (int k=0; k<i; ++k) {
if (hb[k].crossesOverWith (hb[i])) {
hb[i].H = max (hb[i].H, hb[k].H);
}
}

hb[i].H += hb[i].h;
}

int answer = 0;
for (int i=0; i<c; ++i) {
answer = max (answer, hb[i].H);
}

printf ("%d\n", answer);
}

return 0;
}


据说二维线段树能过,下面的一维线段树 + 枚举TLE,伤心,贴着权当纪念吧

#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

#undef _DEBUG

#ifdef _DEBUG
#define debug_printf(...) printf(__VA_ARGS__)
#else
#define debug_printf(...) 0
#endif

struct Node
{
int childMax;
//  int left;
//  int right;
int value;
bool valueDowned;

Node (): childMax(0), /*left(0), right(0),*/value(0), valueDowned(false) {}
Node (int cm,/* int lf, int rt,*/int v, bool vd): childMax(cm),/* left(lf), right(rt), */value(v), valueDowned(vd) {}
};

const int NODES_MAX = 2048;

struct SegmentTree
{
Node node[NODES_MAX];

void downValue (int left, int right, int nd)
{
assert (left < right);
assert (0 < nd && nd < NODES_MAX);

node[nd].valueDowned = true;
node[nd].childMax = node[nd].value;

if (left + 1 == right) {
return;
}

node[nd + nd].valueDowned = false;
node[nd + nd].value = node[nd].value;
node[nd + nd].childMax = node[nd].value;

node[nd + nd + 1].valueDowned = false;
node[nd + nd + 1].value = node[nd].value;
node[nd + nd + 1].childMax = node[nd].value;
}

int maxValue (int rangeLeft, int rangeRight, int left, int right, int nd)
{
if (rangeLeft <= left && right <= rangeRight) {
return node[nd].childMax;
} else if (rangeRight <= left || right <= rangeLeft) {
return 0;
}

if (! node[nd].valueDowned) {
downValue (left, right, nd);
}

if (left + 1 == right) {
return node[nd].value;
} else {
assert (left < right);
}

int mid = (left + right) / 2;
int leftMaxValue = maxValue (rangeLeft, rangeRight, left, mid, nd + nd);
int rightMaxValue = maxValue (rangeLeft, rangeRight, mid, right, nd + nd + 1);

if (leftMaxValue > rightMaxValue) {
return leftMaxValue;
} else {
return rightMaxValue;
}

assert (false);
}

void setValue (int value, int rangeLeft, int rangeRight, int left, int right, int nd)
{
if (rangeLeft <= left && right <= rangeRight) {
node[nd].value = value;
node[nd].childMax = value;
node[nd].valueDowned = false;
return;
} else if (rangeRight <= left || right <= rangeLeft) {
return;
}

if (! node[nd].valueDowned) {
downValue (left, right, nd);
}

if (left + 1 == right) {
node[nd].value = value;
node[nd].childMax = value;
node[nd].valueDowned = true;
return;
} else {
assert (left < right);
}

int mid = (left + right) / 2;
setValue (value, rangeLeft, rangeRight, left, mid, nd + nd);
setValue (value, rangeLeft, rangeRight, mid, right, nd + nd + 1);

if (node[nd + nd].childMax > node[nd + nd + 1].childMax) {
node[nd].childMax = node[nd + nd].childMax;
} else {
node[nd].childMax = node[nd + nd + 1].childMax;
}

node[nd].value = 0;
node[nd].valueDowned = true;
}

void resetAll (int left, int right, int nd)
{
if (left + 1 == right) {
node[nd].childMax = 0;
node[nd].value = 0;
node[nd].valueDowned = true;
return;
} else {
assert (left < right);
}

int mid = (left + right) / 2;
resetAll (left, mid, nd + nd);
resetAll (mid, right, nd + nd + 1);

if (node[nd + nd].childMax > node[nd + nd + 1].childMax) {
node[nd].childMax = node[nd + nd].childMax;
} else {
node[nd].childMax = node[nd + nd + 1].childMax;
}

node[nd].value = 0;
node[nd].valueDowned = true;
}

void print_tree (int left, int right, int nd)
{
if (left >= right) {
return;
}

debug_printf ("node[%d]: left = %d, right = %d, value = %d, valueDowned = %d, childMax = %d\n",
nd, left, right, node[nd].value, node[nd].valueDowned, node[nd].childMax);

if (left + 1 == right) {
return;
} else {
assert (left < right);
}

int mid = (left + right) / 2;
print_tree (left, mid, nd + nd);
print_tree (mid, right, nd + nd + 1);
}
};

SegmentTree tree[1000];

int main (int argc, char **argv)
{
int n, m, c;
while (scanf ("%d%d%d", &m, &n, &c) == 3) {

for (int i=0; i<m; ++i) {
tree[i].resetAll (0, n, 1);

//tree[i].print_tree (0, n, 1);
}

for (int i=0; i<c; ++i) {

int a, b, h, x, y;
scanf ("%d%d%d%d%d", &a, &b, &h, &x, &y);

assert (0 < a && 0 < b);
assert (0 <= x && 0 <= y);
assert (x + a <= m && y + b <= n);

int max = 0;
for (int k=0; k<a; ++k) {
int v = tree[x + k].maxValue (y, y + b, 0, n, 1);

//tree[x + k].print_tree (0, n, 1);
debug_printf ("maxValue = %d\n", v);

if (v > max) {
max = v;
}

debug_printf ("max = %d\n", max);
}

for (int k=0; k<a; ++k) {
tree[x + k].setValue (h + max, y, y + b, 0, n, 1);

//tree[x + k].print_tree (0, n, 1);
}
}

int max = 0;
for (int i=0; i<m; ++i) {
int v = tree[i].maxValue (0, n, 0, n, 1);
if (v > max) {
max = v;
}
}

printf ("%d\n", max);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: