#589. 图图的游戏

【题目描述】:
图图正在玩一个智力游戏:有一个n×n 的01 方格,图图要从中选出一个面积最大的矩形区域,要求这个矩形区域不能有超过k个1。

这么难的问题图图当然不会做了,他想让你帮帮他,你能解决这个问题吗?

【输入描述】:
第一行包含2 个正整数n,k。

接下来n 行每行n 个整数,表示这个01方格。

【输出描述】:
输出1 个整数,表示最大面积。

【样例输入】:
5 4
1 0 1 0 1
0 1 0 0 0
1 0 1 0 0
1 1 1 1 1
0 0 1 0 1
【样例输出】:
12
【时间限制、数据范围及描述】:
时间:1s 空间:256M

对于40%的数据,1≤n≤10;

对于70%的数据,1≤n≤51;

对于100%的数据,1≤n≤501,0≤k≤n×n。

本题n^4的算法想必是人人都会写的,直接一个矩阵前缀和就行了,然后我就想到了二分第四维,结果还是90,最后没想到的是尺取大法居然比二分快得多.
只想说一句:尺取大法好!!!

Code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<deque>
using namespace std;
const int N=505;
int c[N][N],n,q,f[N][N];
int read() {
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
int calc(int r1,int c1,int r2,int c2){
    return f[r2][c2]-f[r2][c1-1]-f[r1-1][c2]+f[r1-1][c1-1];
}
int main(){
    n=read();
    q=read();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            c[i][j]=read();
            f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+c[i][j];
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int k=1;k<=i;k++){
            int l=1;
            for(int j=1;j<=n;j++){
                while(calc(k,l,i,j)>q){
                    l++;
                }
                int x=i-k+1;
                int y=j-l+1;
                ans=max(ans,x*y);
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/ukcxrtjr/p/11577825.html

时间: 2024-08-30 15:25:27

#589. 图图的游戏的相关文章

UOJ #589. 图图的游戏

[题目描述]: 图图正在玩一个智力游戏:有一个n×n 的01 方格,图图要从中选出一个面积最大的矩形区域,要求这个矩形区域不能有超过k个1. 这么难的问题图图当然不会做了,他想让你帮帮他,你能解决这个问题吗? [输入描述]: 第一行包含2 个正整数n,k. 接下来n 行每行n 个整数,表示这个01方格. [输出描述]: 输出1 个整数,表示最大面积. [样例输入]: 5 4 1 0 1 0 1 0 1 0 0 0 1 0 1 0 0 1 1 1 1 1 0 0 1 0 1 [样例输出]: 12

给他任何一套图图图u又哭了

夫人和翻译秃头一天又图图图5634564646464合格合格合格和非官方的活动符合东方给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭了给他任何一套图图图u又哭

数据结构--图--图的数组存储表示,深度优先搜索遍历和广度优先搜索遍历

图有四种存储结构:数组,邻接表,十字链表,邻接多重表.下面以数组为存储结构来实现图的深度优先搜索遍历和广度优先搜索遍历.其中广度优先搜索遍历中有用到STL中的queue,注意头文件的包含.具体代码如下: //图的数组(邻接矩阵)存储表示和深度优先遍历 const int MAX_VERTEX_NUM=20; //最大顶点数 typedef enum {DG,DN,UDG,UDN} GraphKind ;//(有向图,有向网,无向图,无向网) typedef int VRType; typedef

15 图-图的遍历-基于邻接矩阵实现的BFS与DFS算法

算法分析和具体步骤解说直接写在代码注释上了 TvT 没时间了等下还要去洗衣服 就先不赘述了 有不明白的欢迎留言交流!(估计是没人看的了) 直接上代码: 1 #include<stdio.h> 2 #include<queue> 3 #include<iostream> 4 using namespace std; 5 typedef struct{ 6 int Vex[10];//顶点表 7 int Edge[10][10]; 8 int vexnum,arcnum;

【2018.10.22】图图的游戏 / 图图的设计 / 图图的旅行

题目 我是一个小沙比,爆零本领强~ T1 看起来是一道很捞的.做过无数遍的区间最大值. 直接$O(n^3)$做一做就完了…… 具体做法就是预处理每行的前缀和,然后二重循环枚举一个固定的列区间,再用单调队列的思想,从第一行不停向下扩展行区间,如果矩阵内总和$\gt k$ 了就从行区间顶部不停删行,删到矩阵内总和$\le k$ 为止.每当矩阵总和满足限制时,更新矩阵面积最大值即可. 当然如果你很想大战$T1$的话,可以写个$O(n^2*log(n^2))$的主席树? 1 #include<cmath

数据结构(五)图---图的存储结构5种

一:图的抽象数据类型 ADT 图(Graph) Data 顶点的有穷非空集合和边的集合 Operation CreateGraph(*G,V,VR):按照顶点集V和边弧集VR的定义构造图G DestroyGraph(*G):图G存在则销毁 LocateVex(G,u):若图G中存在顶点u,则返回图中位置 GetVex(G,v):返回图中顶点v的值 PutVex(G,v,value):将图G中顶点v赋值给value FirstAdjVex(G,*v):返回顶点v的一个邻接顶点,若顶点在G中无邻接顶

图——图的Prim法最小生成树实现

1,运营商的挑战: 1,在下图标出的城市间架设一条通信线路: 2,要求: 1,任意两个城市间都能够通信: 2,将架设成本降至最低: 2,问题抽象: 1,如何在图中选择 n - 1 条边使得 n 个顶点间两两可达,并且这 n - 1 条边的权值之和最小? 3,最小(大)生成树: 1,仅使用图中的 n - 1 条边连接图中的 n 个顶点: 2,不能使用产生回路的边: 3,各边上的权值总和达到最小(大): 4,寻找最小生成树: 5,使用 prim 方法手工寻找最小生成树: 6,最小生成树算法步骤(pr

图——图的Floyd法最短路径实现

1,Dijkstra 算法一次性求得起始顶点到所有其它顶点的最短路径,如果想要求解任意两个顶点之间的最短路径,可将图中顶点作为起始顶点执行 n 次 Dijkstra 算法就可以了: 2,可能解决方案: 1,算法执行结束后,i 到 j 最短路径值存储于 dist[i][j] 中.最短路径前驱结点存储于 path[N][N] 中: 2,这种方法比较土: 3,问题的提法: 1,已知一个各边权值均大于 0 的带权有向图,对每一对顶点 vi != vj,求出 vi 与 vj 之间的最短路径值以及最短路径上

图——图的Dijkstra法最短路径实现

1,最短路径的概念: 1,从有向图中某一顶点(起始顶点)到达另一顶点(终止顶点)的路径中,其权值之和最小的路径: 2,问题的提法: 1,给定一个带权有向图 G 与起始顶点 v,求从 v 到 G 中其它顶点的最短路径(每条边上都存在有意义的权值): 2,Dijkstra 算法核心是通过已知最短路径寻找未知最短路径: 3,解决思路: 1,Dijkstra 提出按路径长度的递增次序,逐步产生最短路径: 1,首先求出长度最短的一条最短路径,再参照它求出长度次短的一条最短路径,依次类推,直到从起始顶点 v