【DP】【构造】NOIp模拟题 演讲 题解
极其考思维的好题
题目背景
众所周知,$\mathrm{Zdrcl}$是一名天天$\mathrm{AK}$的高水平选手。
作为一民长者,为了向大家讲述自己$\mathrm{AK}$的经验,他决定在一个礼堂里为大家举办一场演讲。题目描述
这个礼堂拥有$N\times M$个位子,排成$N$行$M$列。每个位子都有一盏灯,一开始有的灯是亮的,有的灯是灭的。这个礼堂十分诡异,人们操作一次只能使某一行或某一列(某一行或某一列由操作者你自己来决定)的灯的明暗状态全都发生转变(显然,我们不一定可以把所有的灯都点亮)。
来听演讲的人只会坐在灯已经被点亮的位置, 所以可以听演讲的位置只会是一个只由灯是亮的的位子所组成的矩形(不然坐太乱,$\mathrm{Zdrcl}$会不高兴的) 。
$\mathrm{Zdrcl}$知道会有很多人来听演讲, 所以他希望找到一个经过若干操作后的面积最大的只由灯是亮的的位子所组成的矩形。 这个任务当然由想$\mathrm{AK}$的你来完成啦!
输入输出格式
输入格式:
第一行两个正整数表示$N,M$。
接下来有$N$行,每行有$M$个字符(‘#’表示这个灯初始状态是亮的,‘.’表示这个灯初始状态是暗的)。
输出格式:
一行一个整数表示你找到的矩形的面积。
输入输出样例
输入样例#1:
3 3
..#
##.
.#.输出样例#1:
6输入样例#2:
4 6
.#....
...###
.##.#.
...#..输出样例#2:
9说明
样例1解释
数据范围
对于$5\%$的数据:$N=2,M=2$
对于$15\%$的数据:$N\times M\le 8$
对于$30\%$的数据:$N,M\le 10$
对于$60\%$的数据:$N\le 1\le 10^2$
对于$80\%$的数据:$N\le 4\times 10^2$
对于$100\%$的数据:$N\le 2\times 10^3$
输入文件比较大, 请使用比较快速的读入方法。
提示
这一题写起来不是很困难。
题解:
这个题只要第一步想对了,剩下的DP部分就不难写。主要就是考虑怎么判断是否能全部点亮。
多次手玩可以发现对于可以被全部点亮的部分的特性。因为异或的逆运算还是异或,灯的开关就是在异或。因此我们考虑把矩阵转化为0和1。
上面提到灯的开关是进行了异或,因此对于任意行或列的操作,它们的顺序是可以被打乱的。我们假设先进行列操作,我们要尽可能把序列变为形如
00000
11111
11111
00000
这样,才能在之后只进行行操作时可以完成矩阵的变换。
那么上面给出的矩阵原来可能是这样的
01001
10110
10110
01001
可以发现,它们左右异或的结果总是一列均为1或一列均为0。因为如果一列均为1的话,那么只需要对其中一列进行反转即可;如果一列均为0的话,这两列就是一样的,可以对它们进行相同的操作而达到目的。
1101
1101
1101
1101
不过这样异或会使得矩阵的宽度减小1,我们只需要在计算的时候把这一维加上1就可以了,因为有$latex x$个异或结果,代表了$latex x+1$列。最后再单独处理最优解只占一列的特殊情况。
而有了这样的矩阵,我们的目的就是求最大子矩阵,其中每一列的数字都相同。这样用单调栈可以做到$latex O(nm)$。
当时出题人给出的解法是通过前5%的数据找规律,发现对于一个合法的矩阵,它内部的每一块2×2区域都满足“两种状态出现的次数都是偶数”。
即0出现0次,1出现4次/0出现4次,1出现0次/0出现2次,1出现2次。这样的话感觉条件变少了,不过正确性也可以保证,暂时不写代码。(咕
Code:
#include<cstdio>
#include<cstring>
char c[2222][2222];
int Xor[2222][2222];
int con[2222];
int q[2222],l=0,r=0;
int ext[2222];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%s",c[i]+1); int ans=1,tt=1;
for(int i=1;i<=n;++i)
{
tt=1;
for(int j=1;j<=m;++j)
if(c[i][j]==c[i][j-1])
{
++tt;
ans=ans>tt?ans:tt;
}
else
tt=1;
}
for(int i=1;i<=m;++i)
{
tt=1;
for(int j=1;j<=n;++j)
if(c[i][j]==c[i-1][j])
{
++tt;
ans=ans>tt?ans:tt;
}
else
tt=1;
}
for(int i=1;i<n;++i)
for(int j=1;j<=m;++j)
Xor[i][j]=(c[i][j]!=c[i+1][j]);
for(int i=1;i<=m;++i)
{
l=0,r=0;
for(int j=1;j<n;++j)
{
if(i==1||Xor[j][i]!=Xor[j][i-1])
con[j]=1;
else
con[j]++;
int cnt=0;
while(l<r&&con[j]<con[q[r]])
{
int tmp=(j-q[r]+1+ext[r])*(con[q[r]]);
ans=ans>tmp?ans:tmp;
cnt+=ext[r]+1;//好久没用单调栈做题了,忘记还要加上之前延伸的块……
--r;
}
q[++r]=j;
ext[r]=cnt;
}
for(int j=l+1;j<=r;++j)
{
int tmp=(n-q[j]+1+ext[j])*(con[q[j]]);
ans=ans>tmp?ans:tmp;
}
}
printf("%d\n",ans);
return 0;
}
【DP】【构造】NOIp模拟题 演讲 题解的更多相关文章
- 一些noip模拟题一句话题解
Problem A: 序列 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 12 Solved: 9[Submit][Status][Web Boar ...
- 【入门OJ】2003: [Noip模拟题]寻找羔羊
这里可以复制样例: 样例输入: agnusbgnus 样例输出: 6 这里是链接:[入门OJ]2003: [Noip模拟题]寻找羔羊 这里是题解: 题目是求子串个数,且要求简单去重. 对于一个例子(a ...
- NOIP模拟题汇总(加厚版)
\(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...
- 8.22 NOIP 模拟题
8.22 NOIP 模拟题 编译命令 g++ -o * *.cpp gcc -o * *.c fpc *.pas 编译器版本 g++/gcc fpc 评测环境 位 Linux, .3GHZ CPU ...
- 9.9 NOIP模拟题
9.9 NOIP模拟题 T1 两个圆的面积求并 /* 计算圆的面积并 多个圆要用辛普森积分解决 这里只有两个,模拟计算就好 两圆相交时,面积并等于中间两个扇形面积减去两个三角形面积 余弦定理求角度,算 ...
- noip模拟题题解集
最近做模拟题看到一些好的题及题解. 升格思想: 核电站问题 一个核电站有N个放核物质的坑,坑排列在一条直线上.如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质. 任务:对于给定 ...
- NOIP模拟题17.9.26
B 君的任务(task)[题目描述]与君初相识,犹如故人归.B 君看到了Z 君的第一题,觉得很难.于是自己出了一个简单题.你需要完成n 个任务,第i 任务有2 个属性ai; bi.其中ai 是完成这个 ...
- PAT甲级 模拟题_C++题解
模拟题 PAT (Advanced Level) Practice 模拟题 目录 1008 Elevator (20) 1042 Shuffling Machine (20) 1046 Shortes ...
- 【noip模拟题】迎接仪式(dp+特殊的技巧)
好神的一题... 这是一道DP题,本题的难点在于状态的确定,由于调整是任意的,很难划分状态,我们略微修改一下调整的形式:把一次’j’和’z’交换看做两次变换:’j’->’z’;’z’->’ ...
随机推荐
- 基于 EntityFramework 的数据库主从读写分离架构(2)- 改进配置和添加事务支持
回到目录,完整代码请查看(https://github.com/cjw0511/NDF.Infrastructure)中的目录: src\ NDF.Data.EntityFramew ...
- 为什么rand和srand总是同时出现?
如果没有srand,那么rand在我电脑上运行每次返回的随机数是一样的.如果如果先调用srand,而且srand的参数不一样,那么最后产生的随机数就会不一样?那怎么然srand的参数是不一样的呢? 是 ...
- RabbitMQ(pika模块)
RabbitMQ 基础 2 3 4 5 6 7 8 安装配置epel源 $ rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-r ...
- CF570D Tree Requests
离线 + 树状数组 如果子树中的一个深度的所有点中有两个以上的字母出现了奇数次,那么这个询问的答案就是$No$,其他的情况吧都是$Yes$. 由于只有$26$个字母,我们可以考虑暴力检验,把树映射到$ ...
- Smarty3——从配置文件获取的变量
再使用配置变量前要 引入配置变量即:{$config_load file=‘file_path’}$marty3中可以从配置文件中 用 # 号包起来引用配置文件中的变量({#config_var_na ...
- scala的futue和promise
异步操作的有两个经典接口:Future和Promise,其中的 Future 表示一个可能还没有实际完成的异步任务的结果,针对这个结果可以添加 Callback 以便在任务执行成功或失败后做出对应的操 ...
- spark源码阅读之network(3)
TransportContext用来创建TransportServer和TransportclientFactory,同时使用TransportChannelHandler用来配置channel的pi ...
- hdu 2553 N皇后问题(一维数组详尽解释)
//一维数组解法(注释详尽)//num皇后可以表示第num列,然后枚举num皇后所在的行//二维数组对角线转换为坐标的关系#include<stdio.h> #include<str ...
- Java List集合和Map集合的综合应用
public static void main(String[] args) { //--------------------------------------------------------- ...
- tornado+nginx上传视频文件
[http://arloz.me/tornado/2014/06/27/uploadvideotornado.html] [NGINX REFRER:Nginx upload module] 由于to ...
