示例一:

输入  :

1 2

01

输出:

0

示例二:

输入  :

1 3

101

输出:

1

示例三(自己自测找错误用的):

输入  :

6 6
100111
111011
111111
111111
111111
101111

输出:

16

题意:在由1和0构成的矩形中找到由仅由1构成的第二大的矩形。(前缀和思维)

解题思路:(1)这是比赛后看别人代码的解法,比赛中自己也有这思路,但没考虑周到。运用前缀和思想算出每个位置前面到这个位置一共有多少个连续的1,然后从左上角开始往下算,每次记录当前位置的长度和位置(位置后面用来计算矩形的高度),每次算出当前最大矩形的大小和次大矩形的大小,更新答案。

(2)dfs,感觉自己剪枝做得不够好所以一直超时,还没想出如何不超时的剪枝方法,先留着,复杂度为O(N³),通过率为95%。

不说了,贴代码:

(1)AC代码

 #include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+;
int a[maxn][maxn],max_1=,max_2=;///a数组记录每个位置的前缀和,max_1和max_2为最大和次大
char ss[maxn][maxn];
struct node
{
int num,ins;
}pp[maxn];///记录当前位置的长度和位置
void update(int summ)///更新最大值和次大值
{
if(summ>max_1){
swap(max_1,max_2);swap(summ,max_1);
}
else if(summ>max_2)swap(summ,max_2);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=; i<=n; i++)
scanf("%s",ss[i]);
for(int i=;i<=n;i++){
for(int j=;j<m;j++){
if(ss[i][j]=='')a[i][j+]==;
else if(ss[i][j]=='')a[i][j+]=a[i][j]+;
}
}
for(int j=; j<=m; j++)
{
int r=;
for(int i=; i<=n; i++)
{
int book=i;
while(r&&pp[r].num>a[i][j]){
update((i-pp[r].ins)*pp[r].num);
update((i-pp[r].ins-)*pp[r].num);
book=min(book,pp[r].ins);
r--;
}
pp[++r]={a[i][j],book};
}
while(r){
update(((n+)-pp[r].ins)*pp[r].num);
update(((n+)-pp[r].ins-)*pp[r].num);
r--;
}
}
printf("%d\n",max_2);
return ;
}

(2)有剪枝通过的大佬教我一下

 #include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+;
int a[maxn][maxn],max_1=,max_2=,t;///a数组记录每个位置的前缀和,max_1和max_2为最大和次大
int jlen=,ilen=,rec;///用于记录最小长度,最高高度和当前面积
char ss[maxn][maxn];
void dfs(int x,int y)
{
if(a[x][y])
{
if(a[x][y]>=jlen)
{
ilen++;
rec=ilen*jlen;
if(rec>max_1){
swap(max_1,max_2);swap(rec,max_1);}
else if(rec>max_2)
swap(rec,max_2);
dfs(x-,y);
}
else if(a[x][y]<jlen)
{
ilen++,jlen=a[x][y];
rec=ilen*jlen;
if(rec>max_1)
t=max_1,max_1=rec,max_2=t;
else if(rec>max_2)
max_2=rec;
dfs(x-,y);
}
}
return;
}
int main()
{
int n,m,x,book=;
scanf("%d%d",&n,&m);
for(int i=; i<=n; i++){
scanf("%s",ss[i]);
for(int j=; j<m; j++)
{
if(j==&&ss[i][]=='')
a[i][]=,book++;
else if(ss[i][j]=='')
a[i][j+]=;
else if(ss[i][j]=='')
a[i][j+]=a[i][j]+,book++;
}
}
for(int i=; i<=n; i++)
{
for(int j=; j<=m; j++)
{
if(a[i][j])
{
ilen=,jlen=a[i][j];
rec=ilen*jlen;
if(rec>max_1)
t=max_1,max_1=rec,max_2=t;
else if(rec>max_2)
max_2=rec;
dfs(i-,j);
}
}
}
printf("%d\n",max_2);
return ;
}

(3)上面代码改进深搜极限918msAC(PS:试了横着做和竖着做,发现就只有竖着做能A,可能数据太弱的缘故吧)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+;
int a[maxn][maxn],max_1=,max_2=;
int rec;
int main()
{
int n,m,x,book=;
scanf("%d%d",&n,&m);
for(int i=; i<=n; i++)
for(int j=; j<=m; j++)
{
scanf("%1d",&a[i][j]);
a[i][j]+=a[i-][j]*a[i][j];
}
for(int i=n; i>=; i--)
{
for(int j=m; j>=; j--)
{
if(i*j<=max_2)break;
int ilen=a[i][j],jlen=;
while(ilen)
{
rec=ilen*jlen;
if(rec>=max_1)
max_2=max_1,max_1=rec;
else if(rec>max_2)
max_2=rec;
ilen=min(ilen,a[i][j-jlen]);
jlen++;
}
}
}
printf("%d\n",max_2);
return ;
}

2019牛客暑期多校训练营(第二场)H Second Large Rectangle的更多相关文章

  1. 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)

    题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...

  2. 2020牛客暑期多校训练营 第二场 K Keyboard Free 积分 期望 数学

    LINK:Keyboard Free 我要是会正经的做法 就有鬼了. 我的数学水平没那么高. 三个同心圆 三个动点 求围成三角形面积的期望. 不会告辞. 其实可以\(n^2\)枚举角度然后算出面积 近 ...

  3. 2020牛客暑期多校训练营 第二场 J Just Shuffle 置换 群论

    LINK:Just Shuffle 比较怂群论 因为没怎么学过 置换也是刚理解. 这道题是 已知一个置换\(A\)求一个置换P 两个置换的关键为\(P^k=A\) 且k是一个大质数. 做法是李指导教我 ...

  4. 2020牛客暑期多校训练营 第二场 I Interval 最大流 最小割 平面图对偶图转最短路

    LINK:Interval 赛时连题目都没看. 观察n的范围不大不小 而且建图明显 考虑跑最大流最小割. 图有点稠密dinic不太行. 一个常见的trick就是对偶图转最短路. 建图有点复杂 不过建完 ...

  5. 2020牛客暑期多校训练营 第二场 C Cover the Tree 构造 贪心

    LINK:Cover the Tree 最受挫的是这道题,以为很简单 当时什么都想不清楚. 先胡了一个树的直径乱搞的贪心 一直过不去.后来意识到这类似于最经典长链剖分优化贪心的做法 然后那个是求最大值 ...

  6. 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心

    LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...

  7. 2020牛客暑期多校训练营 第二场 A All with Pairs 字符串hash KMP

    LINK:All with Pairs 那天下午打这个东西的时候状态极差 推这个东西都推了1个多小时 (比赛是中午考试的我很困 没睡觉直接开肝果然不爽 一开始看错匹配的位置了 以为是\(1-l\)和\ ...

  8. 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem

    题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3  4 2 3 4 输出:0 0 1 题解: 认真想一 ...

  9. [题解] 2019牛客暑期多校第三场H题 Magic Line

    题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意:二维平面上有n个不同的点,构造一条直线把平面分成两个点数相同的部分. 题解:对这n个点以x为第一关键 ...

  10. 2020牛客暑假多校训练营 第二场 H Happy Triangle set 线段树 分类讨论

    LINK:Happy Triangle 这道题很容易. 容易想到 a+b<x a<x<b x<a<b 其中等于的情况在第一个和第三个之中判一下即可. 前面两个容易想到se ...

随机推荐

  1. 关于kmp算法

    字符串匹配算法简称kmp 日常安利大佬博客(真的是一篇很好的文章) 觉得百度百科讲的也挺好 就是给出两个字符串a, b 求b在a中的所有位置 next数组:代表当前字符之前的字符串中,有多大长度的相同 ...

  2. 洛谷p3398仓鼠找suger题解

    我现在爱死树链剖分了 题目 具体分析的话在洛谷blog里 这里只是想放一下改完之后的代码 多了一个son数组少了一个for 少了找size最大的儿子的for #include <cstdio&g ...

  3. 【JZOJ6231】【20190625】等你哈苏德

    题目 有\(m\)条线段,每条线段为\([l_i,r_i]\),每条线段可以是黑/白色 有些线段已经被染色,有些需要被确定颜色 询问是否存在一种染色方案,使得对于每一个位置\(i\),覆盖它的线段黑白 ...

  4. LCA的几种做法

    P3379 LCA $ 1:$蜗牛爬式 void dfs(int u,int fa) { f[u]=fa;//预处理father for(int i=head[u]; i; i=e[i].nxt) i ...

  5. Apache Kylin - 大数据下的OLAP解决方案

    OLAPCube是一种典型的多维数据分析技术,Cube本身可以认为是不同维度数据组成的dataset,一个OLAP Cube 可以拥有多个维度(Dimension),以及多个事实(Factor Mea ...

  6. js控制网页窗口一打开就自动全屏

    1.如果不需要开新窗口 在body区加入: <body   onLoad= "javascript:window.resizeTo(screen.availWidth,screen.a ...

  7. Linux上DNS解析总是选择resolv.conf中第二位的DNS服务器IP地址

    问题现象: 在Linux机器上,用户自建了一台DNS服务器.然后改动/etc/resolv.conf将其服务器IP地址添加到第一项.将阿里云的内网DNS放到第二位,然而在测试过程中发现telnet,p ...

  8. SVN更新冲突文件冲突符号的意思

    带黄色感叹号的文件为冲突文件,内容会发生变化并且会存在一些特殊符号: <<<<<<< .mine#Mon Feb 18 20:10:37 CST 2013== ...

  9. Mstar 平台(648)唤醒之串口唤醒

    串口唤醒功能主要是从supernova 待机进入PM后,串口接收PC端口发送过来的特定字串,然后将主板唤醒的功能.与IR,KEYPAD,WOL,CEC,MHL 等等基本流程一致,触发源不一样而已. 待 ...

  10. jsch配置sftp服务器ssh免密登录

    前期对接了一个通过ssh免密登录的需求,是基于原先密码登录sftp服务器的代码上进行改造,实际上代码改动量非常少,趁此机会对自己整理的资料做一下总结. 1. 什么是SFTP SFTP是一个安全文件传送 ...