【NOIP模拟_54测试】【并查集】【二进制】【搜索】【区间序列类】
第一题 Mushroom的序列 大意:
给一个序列,求一段连续最长区间满足:最多改变一个数,使得区间是严格的上升子序列。
解:
直接扫描一遍,记一个最长上升子序列编号。然后从每一个编号为1 的点来判断是否可以将两个序列合并,有两种情况,讨论需要注意多种子情况。。。我可能想的比较复杂,所以第一遍写的时候少考虑了一些相等的情况,就WA 了一个点。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 100005
using namespace std;
int n,num[maxn],f[maxn],last=,l[maxn],pre[maxn],ans;
int main()
{
freopen("seq.in","r",stdin);
freopen("seq.out","w",stdout);
cin>>n;
for (int i=;i<=n;i++)
{
scanf("%d",&num[i]);
if (i==) f[i]=;
else {
if (num[i]>num[i-]) f[i]=f[i-]+;
else {
f[i]=;pre[i]=last;
l[last]=f[i-];last=i;
}
}
}
l[last]=f[n];
ans=;
for (int i=;i<=n;i++)
if (l[i]){
ans=max(l[i],ans);
if (i!=&&num[i+]<num[i-]){
if (num[i]>num[i-]+) ans=max(ans,l[pre[i]]+l[i]);
else ans=max(ans,max(l[pre[i]]+,l[i]+));
}
else if (i!=&&num[i+]>=num[i-]){
if (num[i+]>num[i-]+) ans=max(ans,l[pre[i]]+l[i]);
else if (num[i]>num[i-]+) ans=max(ans,l[pre[i]]+l[i]);
else ans=max(ans,max(l[pre[i]]+,l[i]+));
}
else ans=max(ans,max(l[pre[i]]+,l[i]+));
}
if (ans>n) ans=n;
cout<<ans;
return ;
}
第二题 Mushroom的区间 大意:
一个初始全部为0长度为n的序列,给m个区间,对于区间[l,r]的处理为翻转区间内的数 1->0, 0->1,问这m个区间操作能得到多少个不同的序列(即可以只进行一个区间操作也可以对序列进行多个区间翻转操作得到新序列)。如:当n=3,m=3,区间依次为:1 1 ,2 2 , 3 3 的时候有8种不同的序列。
解:
我们可以通过画图推导出如果没有判重,那么新序列数与n没有关系,=2^m。但是需要判重,有两种情况。
第一种:(横线代表区间)
1
2
3
4
因为 1 区间的翻转等效于 2+3+4 区间的翻转,所以这个情况要排除。同时1+2+3+4也是重复的排除,那么ans不乘2。
第二种:
1
2
3
4
因为2+3+4区间翻转等于翻转 1区间,因为2、3、4它们的重合部分翻转抵消了。
所以,如果把一个区间的 L ,R 当做一条边的端点,在链上连边(双向),如果回到已经到过的点,说明是重复的,那么这样我们可以用并查集来表示,用父亲节点判断是不是走过的就可以了。比较巧妙,值得学习。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 100005
#define P 1000000007
using namespace std;
int n,m,fa[maxn],ans=;//***初值
int find(int x)
{
if (x==fa[x]) return x;
else return fa[x]=find(fa[x]);//return
}
int main()
{
freopen("seg.in","r",stdin);
freopen("seg.out","w",stdout);
cin>>n>>m;
for (int i=;i<=n+;i++)// n+1
fa[i]=i;
for (int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
int a=find(x);
int b=find(y+);//平移右边界
if (a!=b){
ans=(ans*)%P;
fa[a]=b;
}
}
cout<<ans;
return ;
}
第三题 来自风平浪静的明天 大意:
好吧,太扯,不想写。但是其实他的题目更扯。。。
【题目描述】
冬眠了五年,光终于从梦中醒来。
千咲、要,大家都在。
隐约记得“昨天”的海船祭,爱花意外成为贡女,沉入海底。
海面冰封,却有丝丝暖流在冰面之下涌动。
此时,爱花沉睡在祭海女神的墓地。她的胞衣在一点点脱落,化作一簇簇暖流,夹杂着她的感情,向海面上涌去。
爱花,你在哪里?
五年之后,纺已经成为海洋学研究科的大学生。
在纺的帮助下,光得知了海面下海流的情况。
纺告诉光,暖流一旦产生,就会不断地向四周扩散,直到遇到海中的岩石。
红腹海牛,快告诉光,爱花在哪里。
纺帮你绘制了一张海流情况图,长度为N,宽度为M。
海很大,一边有沙滩,一边一望无际,但长度和宽度都不会超过300。沙滩是金黄色的,所以用Y表示。海是蓝色的,所以用B表示。暖流很暖和,所以用H表示
海中有大大小小的石头。石头很危险,所以用X表示
光相信自己一定能找到爱花(爱花的位置只有一种可能)
【输入格式】
第一行包括两个整数N,M。
接下来N行,每行M个字符。
【输出格式】
仅一行,表示爱花的位置(如果你无能为力,请输出 -1 ,只要你尽力,光不会责怪你)
【样例输入】
5 5
YYYHB
YYHHH
YHHXB
BBHBB
BBBBB
【样例输出】
2 3
【数据范围】
对于30%的数据,n,m<=10
对于70%的数据,n,m<=100
对于100%的数据,n,m<=300
【样例解释】
在(2,3)出现第一个H后,经过3s后,出现样例输入的地图。
P.S. Mushroom拜托他GF出的这题= =
解:
考试的时候想的是直接枚举每一个H ,然后判断它是不是。判断的时候我用的dfs,记一个层数,对于有两个数组记录每一个层数有没有H,有没有B,如果存在有一层同时有H,同时有B,那这个就不是ans。但是有一个致命的缺陷就是,有可能对于一个非ans的点,从它开始遍历刚好可以把所有点遍历完,而且没有访问到B,这个时候,我就输出了,然后WA 了9个点。。、所以可以用BFS 解决这个问题。但有可能会超时一个点,再改成手写队列就可以了。
其实可以这样想:找出那一片H的边界,即与B相连 的 H,把它 “变成B” ,然后继续更新新的边界H,以此类推,最后一个就是中心。用一个sco数组来记录,初值是-1,B是0,先用B来更新它旁边的H为1,然后再更新下一个边界H 的值为2,最后最大的那个sco值为中心。但这样也有问题,如果有一边全是不能走的X,Y ,那么有可能在推的时候会把一个夹在这X,Y中间的H 认为是中心。所以在最大sco值之中要选一个周围H 最多的作为中心。代码我还没来得及改。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define maxn 305
using namespace std;
const int zl[][]={{,,-,},{,,,-}};
int num,n,m,mp[maxn][maxn],sco[maxn][maxn],ans1,ans2;
void dfs(int d)
{
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (mp[i][j]==&&sco[i][j]==-){
for (int k=;k<=;k++)
{
int x=i+zl[][k],y=j+zl[][k];
if (sco[x][y]!=-&&sco[x][y]<=d){
sco[i][j]=d+;
num--;
if (num==) return ;
break;
}
}
}
dfs(d+);
}
int main()
{
freopen("calm.in","r",stdin);
freopen("calm.out","w",stdout);
cin>>n>>m;
memset(sco,-,sizeof(sco));
for (int i=;i<=n;i++)
{
char a[maxn];
scanf("%s",a);
for (int j=;j<m;j++)
{
if (a[j]=='Y'||a[j]=='X') mp[i][j+]=;
else if (a[j]=='H') {
mp[i][j+]=;num++;
}
else{
mp[i][j+]=;
sco[i][j+]=;
}
}
}
dfs();
int ma=,mm=-;
for (int i=n;i>=;i--)
for (int j=m;j>=;j--)
if (sco[i][j]>=ma){
ma=sco[i][j];
ans1=i;ans2=j;
}
cout<<ans1<<" "<<ans2;
return ;
}
【NOIP模拟_54测试】【并查集】【二进制】【搜索】【区间序列类】的更多相关文章
- 2018.10.16 NOIP模拟 华莱士(并查集)
传送门 按照题意模拟维护最小的环套树森林就行了. 然而考试的时候naivenaivenaive瞎写了一个错误的贪心. 代码
- 2018.10.23 NOIP模拟 战争(并查集)
传送门 跟bzoj1015: [JSOI2008]星球大战是同一道题啊讲道理. 随便合并一下就能过了. 代码
- UVA - 1151 Buy or Build (买还是建)(并查集+二进制枚举子集)
题意:平面上有n个点(1<=n<=1000),你的任务是让所有n个点连通.可以新建边,费用等于两端点欧几里德距离的平方.也可以购买套餐(套餐中的点全部连通).问最小费用. 分析: 1.先将 ...
- NOIP 2010 关押罪犯 并查集 二分+二分图染色
题目描述: S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值" ...
- 【NOIP模拟】board(线段树维护二进制,树序号化为二进制)
题目背景 SOURCE:NOIP2016-RZZ-2 T3 题目描述 给出这样一棵“二叉树”: 每个节点有左右两个儿子,并如下定义每个节点的高度:假设父亲节点的高度为 h ,那么他的两个儿子的节点的高 ...
- NOIp 2017 奶酪 【并查集】 By cellur925
题目传送门 Orz去年考场上做这道题的我应该还在抱怨没学过空间几何,不一会太困了就开始打瞌睡,然后为了防止睡觉开始在devc++上写默写离骚(逃 思路:如果两个空洞相交,那么把他们并在一个集合里.最后 ...
- HDU 3461 Code Lock(并查集,合并区间,思路太难想了啊)
完全没思路,题目也没看懂,直接参考大牛们的解法. http://www.myexception.cn/program/723825.html 题意是说有N个字母组成的密码锁,如[wersdfj],每一 ...
- 【noip模拟题】日历游戏(博弈论+搜索)
直接搜索即可... 注意不要爆栈..所以我们可以分块搜索... 然后太懒且太弱我就不写了... orz hzwer http://hzwer.com/4954.html [问题描述] moreD和mo ...
- Codeforces 1131 F. Asya And Kittens-双向链表(模拟或者STL list)+并查集(或者STL list的splice()函数)-对不起,我太菜了。。。 (Codeforces Round #541 (Div. 2))
F. Asya And Kittens time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
随机推荐
- 20160805_Cent6.4x64_安装配置(含网卡驱动的配置)
ZC: 全程 root用户 操作. 1.我在BIOS中将 UEFI关闭了,然后 才安装的 Cent6.4x64 (ZC: 安装系统时,一起安装了 gcc等一些编程用的包.本来是想安装QT时少点麻烦的, ...
- java 集合(Vector)不做重点
Vector: 底层也是维护了一个Object数组,实现与ArrayList是一样的, 但其线程是安全的,效率低.除了比较老的系统,是不会用到的. 笔试题:ArrayList 和 Vector 的区别 ...
- webpages框架中使用Html.TextArea()在前台显示多行信息时,如何进行大小、样式的设置
环境:vs2015 webpages框架+razor语法: 目的:服务器进行数据更新操作后,在前台显示更新的相关信息: 后台代码:将更新条数等相关信息存储在一个变量中: @{ var serverIn ...
- sealed(C# 参考)
sealed 修饰符可以应用于类.实例方法和属性.密封类不能被继承.密封方法会重写基类中的方法,但其本身不能在任何派生类中进一步重写.当应用于方法或属性时,sealed 修饰符必须始终与 overri ...
- 1.3 ASP.NET MVC生命周期
ASP.NET MVC的执行生命周期主要分为三个阶段,分别是网址路由对比.执行控制器与动作.执行视图并返回结果.从ASP.NET MVC接受HTTP请求到返回HTTP响应的过程如下图所示.
- PHP读取文件夹目录,按时间排序,大小排序,名字排序
工作中有时候会遇到文件存储数据,但是在前台显示的时候又因为没有数据库,无法使用上传或最后一次修改日期字段排序,所以有了如下代码: <?php $dir = "./";//目录 ...
- C/C++ 关于生成静态库(lib)/动态库(dll)文件如何使用(基于windows基础篇)
1. 首先,如何制作一个静态库(lib)? 额, 对于静态库,我们知道,里头是不应该有Main函数,它只是一个配合文件.之所以称之为lib静态库,其实就是指,我们需要用到lib里头的函数时,我们才会去 ...
- 20145236 《Java程序设计》实验一实验报告
北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.04.08 实验名称:Java开发环境的熟悉(Linux + Eclipse) 实 ...
- WCF学习笔记
1,关于WCF/web service/WSE Web Service:是行业标准,也就是Web Service 规范,也称作WS-*规范,既不是框架,也不是技术.它有一套完成的规范体系标准,而且在持 ...
- word-wrap word-break white-space 用法。
一.word-wrap使用: 语法: word-wrap : normal | break-word 取值说明: 1.normal和break-word,其中normal为默认值,当其值为normal ...