题意: 给你n排m列的座位,其中‘.’代表空位,‘*’代表已占用。给你k个人, 这k个人只能连续坐在一排或者一列,问你有多少种安排方式。
思路: 由于一定连续,所以情况就很简单了,分别针对一行或一列来分析, 可以发现规律:定义X是一行或一列中连续的‘.’的个数,安排方式数 为X-k+1。注意特判当k==1时,我们会把一个点一排算一次,一列 算一次,除以2即可排除重复。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<sstream>
#include<queue>
#define ll long long
using namespace std;
char mp[2020][2020];
ll n,m,k;
int main()
{
while(~scanf("%lld%lld%lld",&n,&m,&k))
{
for(ll i=1;i<=n;i++)scanf("%s",mp[i]+1);
ll ans=0,num=0;
if(k==1) //k==1,防止重复,直接计算有几个'.'
{
for(ll i=1;i<=n;i++)
{
for(ll j=1;j<=m;j++)
{
if(mp[i][j]=='.')num++;
}
}
printf("%lld\n",num);
continue;
}
for(ll i=1;i<=n;i++) //计算每一排方案数
{
num=0;
for(ll j=1;j<=m;j++)
{
if(mp[i][j]=='.')num++;
else
{
num=num-k+1;
if(num>0)ans+=num;
num=0;
}
}
num=num-k+1;
if(num>0)ans+=num;
}
for(ll i=1;i<=m;i++) //计算每一列方案数
{
num=0;
for(ll j=1;j<=n;j++)
{
if(mp[j][i]=='.')num++;
else
{
num=num-k+1;
if(num>0)ans+=num;
num=0;
}
}
num=num-k+1;
if(num>0)ans+=num;
}
printf("%lld\n",ans);
}
return 0;
}