第一题 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测试】【并查集】【二进制】【搜索】【区间序列类】的更多相关文章

  1. 2018.10.16 NOIP模拟 华莱士(并查集)

    传送门 按照题意模拟维护最小的环套树森林就行了. 然而考试的时候naivenaivenaive瞎写了一个错误的贪心. 代码

  2. 2018.10.23 NOIP模拟 战争(并查集)

    传送门 跟bzoj1015: [JSOI2008]星球大战是同一道题啊讲道理. 随便合并一下就能过了. 代码

  3. UVA - 1151 Buy or Build (买还是建)(并查集+二进制枚举子集)

    题意:平面上有n个点(1<=n<=1000),你的任务是让所有n个点连通.可以新建边,费用等于两端点欧几里德距离的平方.也可以购买套餐(套餐中的点全部连通).问最小费用. 分析: 1.先将 ...

  4. NOIP 2010 关押罪犯 并查集 二分+二分图染色

    题目描述: S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值" ...

  5. 【NOIP模拟】board(线段树维护二进制,树序号化为二进制)

    题目背景 SOURCE:NOIP2016-RZZ-2 T3 题目描述 给出这样一棵“二叉树”: 每个节点有左右两个儿子,并如下定义每个节点的高度:假设父亲节点的高度为 h ,那么他的两个儿子的节点的高 ...

  6. NOIp 2017 奶酪 【并查集】 By cellur925

    题目传送门 Orz去年考场上做这道题的我应该还在抱怨没学过空间几何,不一会太困了就开始打瞌睡,然后为了防止睡觉开始在devc++上写默写离骚(逃 思路:如果两个空洞相交,那么把他们并在一个集合里.最后 ...

  7. HDU 3461 Code Lock(并查集,合并区间,思路太难想了啊)

    完全没思路,题目也没看懂,直接参考大牛们的解法. http://www.myexception.cn/program/723825.html 题意是说有N个字母组成的密码锁,如[wersdfj],每一 ...

  8. 【noip模拟题】日历游戏(博弈论+搜索)

    直接搜索即可... 注意不要爆栈..所以我们可以分块搜索... 然后太懒且太弱我就不写了... orz hzwer http://hzwer.com/4954.html [问题描述] moreD和mo ...

  9. 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 ...

随机推荐

  1. 如何定位摄像机,使物体在屏幕上始终具有相同的像素宽度和高度?(threes)

    from How to position the camera so that the object always has the same pixel width and height on the ...

  2. js中Math.random()生成指定范围数值的随机数

    http://www.111cn.net/wy/js-ajax/57062.htm Math.random() 这个方法相信大家都知道,是用来生成随机数的.不过一般的参考手册时却没有说明如何用这个方法 ...

  3. shell中for循环

    shell中for循环总结 最常用的就是遍历操作某一类文件,比如批量建索引. for i in `ls` do samtools faidx $i done 注意:for末尾不需要冒号(:),循环的代 ...

  4. 矩阵奇异值分解(SVD)及其应用

    机器学习中的数学(5)-强大的矩阵奇异值分解(SVD)及其应用(好文) [简化数据]奇异值分解(SVD) <数学之美> 第15章 矩阵运算和文本处理中的两个分类问题

  5. PacBio & BioNano (Assembly and diploid architecture of an individual human genome via single-molecule technologies)

    Assembly and diploid architecture of an individual human genome via single-molecule technologies 文章链 ...

  6. Call requires API level 3 (current min is 1)

    结果出现“Call requires API level 3 (current min is 1): 解决方法: 在工程上点击右键 -> Android Tools -> Clear Li ...

  7. Java substring() 方法

    Java String类 substring() 方法返回字符串的子字符串. 语法 public String substring(int beginIndex) 或 public String su ...

  8. as(C# 参考)

    原文地址:https://msdn.microsoft.com/zh-cn/library/cscsdfbt(v=vs.110).aspx 可以使用 as 运算符执行转换的某些类型在兼容之间的引用类型 ...

  9. 30 个有用的 HTML5 和 CSS3 表单设计

    基本上表单是任何一个网站都必须要用到的元素,本文介绍的这 30 个设计方案供你参考,这些方案如果要单独下载完整可运行的文件则需要支付2-5美元的费用. 1. Fresh Forms 2. Pretty ...

  10. 离线网页制作器(beta1.0)

    package hhuarongdao; /* *使用方法: 先选择保存路径,然后输入相应的网址, *然后会得到那个网页的离线版的 内容 * */ import java.awt.BorderLayo ...