救救萌新!

P2363 马农

lxy__ @ 2020-08-07 20:19:57

题解里 d 数组是存矩阵和的

根据题目里面“注意:收益可能是负数,养马也不是包赚的,马匹也可能出现生病死亡等意外。”这一句,矩阵和出现负数可能导致越界。

为此我开了 map,TLE 了好几次,改成普通数组就过了。求助各位巨佬是什么原因。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;

const int N = 53;
int n, ans = 0, a[N][N], sum[N][N][N][N], sum2[N][N][N][N], f[11111111];
//原先的 f 数组是 map

int main()
{
    scanf("%d", &n);

    memset(sum, 0, sizeof(sum));
    memset(sum2, 0, sizeof(sum2));

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            scanf("%d", &a[i][j]);

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
        {
            sum[i][j][i][j] = a[i][j];
            for(int k = i; k <= n; k++)
                for(int h = j; h <= n; h++)
                    sum[i][j][k][h] = a[k][h] + sum[i][j][k - 1][h] + 
                    sum[i][j][k][h - 1] - sum[i][j][k - 1][h - 1];
        }

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
        {
            sum2[i][j][i][j] = a[i][j];
            for(int k = i; k > 0; k--)
                for(int h = j; h <= n; h++)
                    sum2[i][j][k][h] = a[k][h] + sum2[i][j][k + 1][h] + 
                    sum2[i][j][k][h - 1] - sum2[i][j][k + 1][h - 1];
        }

    for(int i = 2; i <= n; i++)
        for(int j = 2; j <= n; j++)
        {
            for(int k = i - 1; k > 0; k--)
                for(int h = j - 1; h > 0; h--)
                    f[sum[k][h][i - 1][j - 1]]++;
            for(int k = i + 1; k <= n + 1; k++)
                for(int h = j + 1; h <= n + 1; h++)
                    ans += f[sum[i][j][k - 1][h - 1]];

            for(int k = i - 1; k > 0; k--)
                for(int h = j - 1; h > 0; h--)
                    f[sum[k][h][i - 1][j - 1]] = 0;

            for(int k = i + 1; k <= n + 1; k++)
                for(int h = j - 1; h > 0; h--)
                    f[sum2[k - 1][h][i][j - 1]]++;
            for(int k = i - 1; k > 0; k--)
                for(int h = j + 1; h <= n + 1; h++)
                    ans += f[sum2[i - 1][j][k][h - 1]];

            for(int k = i + 1; k <= n + 1; k++)
                for(int h = j - 1; h > 0; h--)
                    f[sum2[k - 1][h][i][j - 1]] = 0;
        }
    printf("%d", ans);
    return 0;
}

by LucasXu80 @ 2020-08-07 20:21:43

萌新切蓝题,我自闭了。


by Starlit_Night @ 2020-08-07 20:27:05

萌新切dp,我自闭了


by Smile_Cindy @ 2020-08-07 20:28:09

@lxy__

map的单次访问是 O(\log n) 的,n 为 map的元素个数。


by Smile_Cindy @ 2020-08-07 20:28:41

更多map的信息可以去这里


by lxy__ @ 2020-08-07 20:32:02

@Alpha

这确实是,map会多带一个log

我主要想问问为什么普通数组不会越界?如果普通数组越界是不是还有开map以外的写法?

orz感谢大佬回复


by Smile_Cindy @ 2020-08-07 20:33:26

@lxy__

普通数组确实会越界,不过你可以考虑把sum加上一个足够大的数再放到数组里面去。


by lxy__ @ 2020-08-07 20:38:11

@Alpha

可能是数据强度不够,而且也没有说明 a[i][j] 的范围。我怀疑数据根本没有负数。最好是修改题面或者数据更加严谨吧

谢谢大佬提供思路qwq


by shyyhs @ 2020-08-14 14:13:15

这题是真的恶心,数据范围都是假的


|