zoukankan      html  css  js  c++  java
  • Py&hyh想脱单

    Py&hyh想脱单

    Description

    总所周知,,py和hyh有十分浓烈的脱单意愿,但是非常不幸,在一个风和日丽的下午,他们穿越到一个没有妹子的世界,他必须回答一个问题才能回到本来的世界,这个问题是给出一个nm的矩阵,然后有q次操作,每一个操作,给出xi,yi,ti,表示在ti时刻摧毁(xi,yi)这个格子,然后他们要求出一个最早时刻,出现至少一个kk的矩阵被毁坏,注意:一个kk矩阵被毁坏的意思是某一个kk的矩阵中的每一个格子都被摧毁过一次或一次以上。聪明的acmer能帮他们回答这个问题吗(如果没人能ac这个题,就代表他们两个没有脱单的可能了哦)

    Input

    Input:采用多组输入第一行输入n,m,k,q,(1 ≤ n, m ≤ 500, 1 ≤ k ≤ min(n, m), 1 ≤ q ≤ n·m)分别代表nm的矩阵,kk的矩阵,和q次操作接下来q行每一行输入xi,yi,ti(1 ≤ xi ≤ n, 1 ≤ yi ≤ m, 0 ≤ t ≤ 1e6),代表,在ti这个时刻,xi,yi这个位置会被摧毁

    Output

    Out:输出一行,代表最早时刻出现至少一个k*k的矩阵被毁坏如果永远不存在这一个时刻,输出-1

    Sample Input 1 

    2 3 2 5
    2 1 8
    2 2 8
    1 2 1
    1 3 4
    2 3 2

    Sample Output 1

    8

    Sample Input 2 

    3 3 2 5
    1 2 2
    2 2 1
    2 3 5
    3 2 10
    2 1 100

    Sample Output 2

    -1
    

    题目求的是出现至少一个k*k的矩阵被毁坏的最早时刻,可以想到时间越长,轰炸次数也是越多的,然后出现k*k的矩阵被毁坏的几率也是越大的,因此可以看出这是符合单调性的,所以可以用二分枚举时间mid,判断mid时间是否满足,若满足往前面时间找满足条件的更小的时间,若不满足则往后找。我感觉这题判断轰炸之后,是否存在1个k*k的矩阵才是难点,做法是mp【i】[j],1表示当前格子被轰炸了,0表示没有被轰炸,然后用sum[i][j]记录每个格子对应的左上方向(感觉更前缀和很相似,左上方向可以理解为是1<=列数<=j,1<=行数<=i这个范围内)被轰炸的格子数(也就是mp[I][J]为1的格子的数量),然后暴力枚举整个地图里k*k的矩阵,对一个k*k的矩阵用之前求的sum[][]数组求该矩阵内被轰炸的格子的数量,若等于k*k说明当前枚举的这个矩阵就是满足条件的矩阵。

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 505
    struct node
    {
        int t,x,y;
    
    }boom[maxn*maxn];
    int mp[maxn][maxn],sum[maxn][maxn];
    int n,m,k,q;
    bool cmp(const node&a,const node&b)
    {
        return a.t<b.t;
    }
    int query(int xa,int ya,int xb,int yb)
    {
        return sum[xb][yb]-sum[xa-1][yb]-sum[xb][ya-1]+sum[xa-1][ya-1];
    }
    bool check(int t)
    {
        for(int i=0;i<=n+1;i++)
            for(int j=0;j<=m+1;j++)
                mp[i][j]=sum[i][j]=0;
        for(int i=1;i<=q;i++)
        {
            if(boom[i].t<=t)
                mp[boom[i].x][boom[i].y]=1;
            else
                break;
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                sum[i][j]=mp[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
    
            }
        for(int i=1;i<=n-k+1;i++)
            for(int j=1;j<=m-k+1;j++)
            {
                int x=i,y=j,xx=i+k-1,yy=j+k-1;
                if((k*k)==query(x,y,xx,yy))
                    return true;
    
            }
        return false;
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        while(cin>>n>>m>>k>>q)
        {
            if(n==0&&m==0&&k==0&&q==0)
                 break;
            for(int i=1;i<=q;i++)
            {
    
                cin>>boom[i].x>>boom[i].y>>boom[i].t;
    
            }
            sort(boom+1,boom+q+1,cmp);
            int ans=-1;
            int low=0,up=1000000+10,mid;
            while(low<=up)
            {
                mid=(low+up)/2;
                if(check(mid))
                {
    
                    ans=mid;
                    up=mid-1;
                }
                else
                    low=mid+1;
            }
            cout<<ans<<endl;
    
        }
    
        return 0;
    
    }
    
  • 相关阅读:
    题解 CF171G 【Mysterious numbers
    题解 P1157 【组合的输出】
    题解 P3955 【图书管理员】
    题解 P2036 【Perket】
    题解 CF837A 【Text Volume】
    题解 CF791A 【Bear and Big Brother】
    题解 CF747A 【Display Size】
    题解 P1332 【血色先锋队】
    题解 P2660 【zzc 种田】
    题解 P4470 【[BJWC2018]售票】
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754973.html
Copyright © 2011-2022 走看看