Gym 102091L Largest Allowed Area(二分+暴力枚举+输入挂)

题意:给出一个n*m的矩阵,每个单元可能是1或0,要求找一个尽可能大的方阵,使得里面最多只能有一个1。

思路:由于它要的是方阵,就比较简单了。枚举每一个点,对于每一个点,二分方阵边长,利用前缀和确定该边长的方阵是否可行。复杂度n^2log(n),需要加个输入挂才能过

#include<bits/stdc++.h>
#include<iostream>
#include<queue>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<cstdio>
#include<map>
#include<stack>
#include<vector>
#define rep(i,e) for(int i=0;i<(e);++i)
#define rep1(i,e) for(int i=1;i<=(e);++i)
#define repx(i,x,e) for(int i=(x);i<=(e);++i)
#define pii pair<int,int>
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define IOS ios::sync_with_stdio(false);cin.tie(0)
typedef long long ll;
using namespace std;

#ifdef LOCAL
template<typename T>
void dbg(T t){
    cout<<t<<" "<<endl;
}
template<typename T, typename... Args>
void dbg(T t, Args... args){
    cout<<t<<" ";dbg(args...);
}


#else
#define dbg(...)
#endif // local
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int mod = 1e9+7;
const int N = 1e4+10;
typedef long long ll;
#define K 137
const int maxn = 1e3+10;
const int maxm =4e5+10;

int mp[maxn][maxn];
template <typename T>
inline bool scd (T &ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) return 0; //EOF
    while (c != '-' && (c < '0' || c > '9') ) {
        if((c = getchar()) == EOF) return 0;
    }
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return true;
}


void work(){
   int t,n,m;
   scd(t);
   while(t--){
        scd(n);
        scd(m);
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                scd(mp[i][j]);
                mp[i][j] += (mp[i-1][j]+mp[i][j-1]-mp[i-1][j-1]);
            }
        }
        int l,r;
        int res = 1;
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                l = 1;
                r = min(n,m);
                int tmp = 0;
                while(l <= r){
                    int md = (l+r) >> 1;
                    if(i+md <=n && j+md <= m && mp[i+md][j+md] - mp[i+md][j-1] - mp[i-1][j+md] + mp[i-1][j-1] <= 1){
                        tmp = md;
                        l = md+1;
                    }
                    else
                        r = md-1;
                }
                res = max(res,tmp);
            }
        }
        printf("%d\n",res+1);
   }
}


int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif // LOCAL
    IOS;
    work();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值