codeforces 846D Monitor (二分+二維字首和)
Recently Luba bought a monitor. Monitor is a rectangular matrix of size n × m. But then she started to notice that some pixels cease to work properly. Luba thinks that the monitor will become broken the first moment when it contains a square k × kconsisting entirely of broken pixels. She knows that q
Input
The first line contains four integer numbers n
Each of next q lines contain three integer numbers x
We consider that pixel is already broken at moment ti.
Output
Print one number — the minimum moment the monitor became broken, or "-1" if it's still not broken after these q pixels stopped working.
Examples
Input
2 3 2 5 2 1 8 2 2 8 1 2 1 1 3 4 2 3 2
Output
8
Input
3 3 2 5 1 2 2 2 2 1 2 3 5 3 2 10 2 1 100
Output
-1
PS:題意:在一個n*m的平面上,有n*m個點。但是有一些點,在某個時間後有一些點要損壞,現在求能使一個k*K平面內所有點都是損壞的最短時間,不存在這個時間輸出-1。
題解:先二分一個答案,在判斷這個時間的時候是否有滿足題意。再判斷的時候用字首和。在判斷用 二分的答案時。宣告一個二維陣列,把在這個時間以前壞的點都賦值為1,其他賦值為0。然後用字首和判斷是否有一個大小為K*K的範圍內,陣列的所有和都為1,若是有,直接繼續二維,直到找到最小時間,要是二分結束後沒有,直接輸出-1。(注意在陣列中橫豎方向是反過來的)
#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=5e2+10;
const int mod=1e9+7;
const int inf=1e9;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
typedef long long ll;
using namespace std;
struct node
{
int x,y,t;
}a[maxn*maxn];
int cnt[maxn][maxn],n,m,k,p;
int check(int mid)
{
me(cnt,0);//賦初值。
for(int i=1;i<=p;i++)
if(a[i].t<=mid)
cnt[a[i].y][a[i].x]=1;//說明在該時間前該點已經壞掉了。
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cnt[i][j]+=cnt[i-1][j]+cnt[i][j-1]-cnt[i-1][j-1];
if(i>=k&&j>=k&&cnt[i][j]-cnt[i-k][j]-cnt[i][j-k]+cnt[i-k][j-k]==k*k)//判斷是否有平面滿足
return 1;
}
return 0;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&p);
for(int i=1;i<=p;i++)
scanf("%d%d%d",&a[i].y,&a[i].x,&a[i].t);//在陣列中方向橫豎相反的。
int l=-1,r=inf+1;
while(l+1<r)//不能是“<=”,那樣因為下面沒有mid賦值時沒有減一。
{
int mid=(l+r)>>1;
if(check(mid))
r=mid;
else
l=mid;
}
if(r==inf+1)
cout<<"-1"<<endl;
else
cout<<r<<endl;
return 0;
}