列表

详情


NC206243. AnimalProtection

描述

保护野生动物,人人有责。
多多想从一块N × M大小的陆地中选取一块矩形陆地建立自然保护区,但是某些陆地已经有其他野生动物居住,多多选取时必须避开这些陆地,请问他有多少种选取方法呢?(正方形是特殊的矩形,答案可能过大,请对答案取模1000000007)

输入描述

第一行输入两个正整数N,M (1 ≤ N ≤ 1000,1 ≤ M ≤ 1000)
接下来N行,每行输入长度为M的字符串。
(字符'O'代表可选陆地,字符'X'代表该陆地已有动物居住)

输出描述

输出一个整数,为多多的选取方法(答案可能过大,请对答案取模1000000007)

示例1

输入:

2 2
XO
OO

输出:

5

说明:

选取方法有5种,设左上角陆地为(1, 1)
第一种:选取(1, 2)      第二种:选取(2, 1)
第三种:选取(2, 2)      第四种:选取(1, 2),(2, 2)
第五种:选取(2, 1),(2, 2)

示例2

输入:

3 3
XOO
OXO
OOX

输出:

10

说明:

可以看做有两个样例一的可选形状,所以选取方法有10种

示例3

输入:

4 4
OOOX
OOXO
OOOO
XOOO

输出:

45

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 22ms, 内存消耗: 5352K, 提交时间: 2020-06-15 11:47:55

#include <bits/stdc++.h>

using namespace std;

#define ll long long
ll input(){
	ll x=0,f=0;char ch=getchar();
	while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return f? -x:x;
}

const ll mod=1000000007;
const int N=1007;

int n,m;
char a[N][N];
int stk[N],cnt[N][N];

int main(){
	ll Ans=0;
	n=input(),m=input();
	for(int i=1;i<=n;i++){
		scanf("%s",a[i]+1);
		ll sum=0,top=0;
		for(int j=1;j<=m;j++){
			if(a[i][j]=='O') cnt[i][j]=cnt[i-1][j]+1;
			sum+=cnt[i][j];
			while(top&&cnt[i][stk[top]]>cnt[i][j]){
				sum-=(stk[top]-stk[top-1])*(cnt[i][stk[top]]-cnt[i][j]);
				top--;
			}
			stk[++top]=j;
			Ans=(Ans+sum%mod)%mod;
		}
	}
	printf("%lld\n",Ans);
}

C++11(clang++ 3.9) 解法, 执行用时: 21ms, 内存消耗: 2524K, 提交时间: 2020-06-19 19:16:52

#include<bits/stdc++.h>
using namespace std;

const int mod=1e9+7;
char R[1005][1005];
int main()
{
    int i,j,t,n,m,ans=0,DP[1005]={0},h[1005]={0},S[1005]={0};
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)scanf("%s",R[i]+1);
    for(i=1;i<=n;i++)
    {
		for(t=0,j=1;j<=m;j++)
		{
			if(R[i][j]=='O')h[j]++;
    		else h[j]=0;
			while(t&&h[S[t]]>=h[j])t--;
			DP[j]=(DP[S[t]]+(long long)h[j]*(j-S[t])%mod)%mod;
			ans=(ans+DP[j])%mod,S[++t]=j;
		}
	}
	printf("%d\n",ans);
}

上一题