问题 E: 种南瓜

时间限制: 2 Sec 内存限制: 128 MB
题目描述 一班的同学们决定在班上种南瓜时,pac 感到十分震惊,因为种南瓜是分耗费班级空间的。一班拥有一块 n×m 的地,可以在其中任意一个单元格上种南瓜秧,而南瓜会长在种上的相邻格子,一个格子最多长一个南瓜 。

当然,并不像 MC 中的南瓜长成方式,一班的南瓜经过基因变异,一只南瓜秧可以长出多个南瓜,也就是说,如果四周都没有被占用,仅种下一枝就可收获 4 个南瓜。

pac 已经得知同学们种南瓜的具体方案,她想知道最多可以收获多少个南瓜。

班长 Marser 还想知道,如果南瓜没有经过变异,也就是说一枝南瓜秧只能长出最多一个南瓜,合理种植,这块地上最多能出南瓜的数量 。

输入
第一行两个正整数 n、m(2≤m,n≤5000),为地的大小 。
第 2−n+1 行 ,每行 m 个数字,第 i 行第 j 个数字为 0 或 1,如果等于 1,表示 ai,j这块地上将种下南瓜秧;如果为 0,表示不种。

输出
输出一行两个整数 P、M,分别回答 pac 和 Marser 的问题 。

样例输入 Copy

5 6
0 0 0 0 0 0
0 1 1 0 0 0
0 0 1 1 0 0
0 0 1 0 1 0
0 0 0 0 0 0
样例输出 Copy
11 24

重点来了:
题解:知识点就是枚举
首先说明一点,这个题得到的瓜可以在nm的外一层,就是将nm的扩成(n+2)*(m+2)的这一点就有点坑。但外一层只能是瓜或者没有,不能是瓜籽。di
这是那个公式的理解:有些牵强,
图片说明
代码:

#include <map>
#include <queue>
#include <string>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <math.h>
typedef long long ll;
using namespace std;
const int maxn=2e5+1010;
#define inf 0x3f3f3f3f
#define sf scanf
#define pf printf
const int mod=19260817;
const int MOD=10007;
const int dx[5]={0,0,1,-1};
const int dy[5]={1,-1,0,0};

inline int read() {
    int x=0;
    bool t=false;
    char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}

priority_queue<ll , vector<ll> , greater<ll> > mn;//上  小根堆         小到大
priority_queue<ll , vector<ll> , less<ll> > mx;//下       大根堆      大到小
//map<ll,ll>mp;

ll n,m,t,l,r,p;
ll sum,ans,res,cnt,flag;
int dp[5010][5010];


int main() {
    //sf("%lld%lld",&n,&m);
    n=read();
    m=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            dp[i][j]=read();

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(dp[i][j]==1){
                for(int k=0;k<4;k++){
                if(dp[i+dx[k]][j+dy[k]]==0){
                    dp[i+dx[k]][j+dy[k]]=2;
                    ans++;
                }
                }
            }
    pf("%lld %lld\n",ans,2*(n+m)-4+(n-2)*(m-2)/2);
    return 0;
}