参考:http://blog.youkuaiyun.com/just_sort/article/details/78322659
D. Monitor
题意:一份n*m的显示屏上某些像素点(xi,yi)在t[i]时间会坏掉,如果坏的像素点连成k*k大小,这个显示屏就不能用了,问显示屏损坏的最小的时间,如果不会损坏,输出-1
解法:直接2分时间,那么这个问题就变成了能否找到k*k的矩阵,直接二维前缀和O(n^2)即可。
题解说用二分+前缀和。
这二维rmq也可以
#include<bits/stdc++.h>
using namespace std;
#define maxn 510
#define INF 0x3f3f3f3f
int dp[maxn][maxn][10][10];
int mm[maxn];
int val[maxn][maxn];
void initRMQ(int n,int m)
{
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
dp[i][j][0][0]=val[i][j];
for(int ii=0;ii<=mm[n];++ii)
for(int jj=0;jj<=mm[m];++jj)
if(ii+jj)
for(int i=1;i+(1<<ii)-1<=n;++i)
for(int j=1;j+(1<<jj)-1<=m;++j)
{
if(ii) dp[i][j][ii][jj]=max(dp[i][j][ii-1][jj],dp[i+(1<<(ii-1))][j][ii-1][jj]);
else dp[i][j][ii][jj]=max(dp[i][j][ii][jj-1],dp[i][j+(1<<(jj-1))][ii][jj-1]);
}
}
int rmq(int x1,int y1,int x2,int y2)
{
int k1=mm[x2-x1+1];
int k2=mm[y2-y1+1];
x2=x2-(1<<k1)+1;
y2=y2-(1<<k2)+1;
return max(max(dp[x1][y1][k1][k2],dp[x1][y2][k1][k2]),max(dp[x2][y1][k1][k2],dp[x2][y2][k1][k2]));
}
int main()
{
mm[0]=-1;
for(int i=1;i<maxn;++i) mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
int n,m,k,q;
scanf("%d%d%d%d",&n,&m,&k,&q);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
val[i][j]=INF;
while(q--)
{
int x,y,t;
scanf("%d%d%d",&x,&y,&t);
val[x][y]=t;
}
initRMQ(n,m);
int ans=INF;
for(int i=1;i+k-1<=n;++i)
for(int j=1;j+k-1<=m;++j)
{
int tmp=rmq(i,j,i+k-1,j+k-1);
if(ans==-1||tmp<ans) ans=tmp;
}
if(ans>=INF) ans=-1;
printf("%d\n",ans);
return 0;
}
1573

被折叠的 条评论
为什么被折叠?



