您的位置:首页 > Web前端

Problem B. Safe Squares Google APAC 2017 University Test Round C

2017-02-03 12:12 721 查看
这一题居然是DP,打死我也看不出来==

maxsq[i][j]表示以[i,j]为右下端点的最大safe square的边长,其中square属于[0,0]..[i,0]..[i,j]..[0,j]范围内。

如果[i,j]有monster,那么以[i,j]为端点的safe square不存在,maxsq[i][j]=0

如果[i,j]没有monster,那么最大safe square的边长由三个相邻点[i][j-1],[i-1][j],[i-1][j-1]的最短边长决定,因为max safe square要保证是个连通区域。这个性质举几个例子画个图就能看出来。

对于每个max safe square,在max safe square内以[i][j]结尾的safe square的个数就是边长。因为每个[i][j]对应的safe square个数是disjoint的,直接相加即为最后结果。

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>

using namespace std;

//2017 RoundC Problem B. Safe Squares
int T;
int R;
int C;
int K;
const int maxn=3010;
int mp[maxn][maxn];
int maxsq[maxn][maxn];
int main()
{
freopen("B-large-practice.in","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d", &T);
for(int ca=1;ca<=T;ca++)
{
scanf("%d %d %d",&R,&C,&K);
memset(mp,0,sizeof(mp));
memset(maxsq,0,sizeof(maxsq));
for(int i=0;i<K;i++)
{
int ri;
int ci;
scanf("%d %d",&ri,&ci);
mp[ri][ci]=1;
}
for(int i=0;i<R;i++)
{
maxsq[i][0]=(mp[i][0]==0?1:0);
}
for(int j=0;j<C;j++)
{
maxsq[0][j]=(mp[0][j]==0?1:0);
}
for(int i=1;i<R;i++)
{
for(int j=1;j<C;j++)
{
if(mp[i][j]==0)
{
int tmp=min(maxsq[i-1][j],maxsq[i-1][j-1]);
tmp=min(tmp,maxsq[i][j-1]);
maxsq[i][j]=tmp+1;
}
else
{
maxsq[i][j]=0;
}
}
}
long long ans=0;
for(int i=0;i<R;i++)
{
for(int j=0;j<C;j++)
{
//cout<<maxsq[i][j]<<" ";
ans+=maxsq[i][j];
}
//cout<<endl;
}
printf("Case #%d: %lld\n",ca,ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: