第一题 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. Wincap安装出现“error opening file for writing wpcap.dll”之解决办法

    Wincap安装出现"error opening file for writing wpcap.dll"之解决办法 安装Wireshark时,一直出现下面的错误,选择忽略这个错误, ...

  2. Eclipse NDK 配置

    一.关于NDK:NDK全称:Native Development Kit. 1.NDK是一系列工具的集合. NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java ...

  3. 2015苹果WWDC开发者大会

    2015苹果WWDC开发者大会 (1)本届主题为“the epicenter of change(变革的中心)” (2)iOS 9.OS X.watchOS三款重要系统更新以及其他服务 (3)iOS ...

  4. C# 中的弱引用 WeakReference

    C#中的弱引用(WeakReference)   我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的.我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET ...

  5. OpenCV图像处理中常用函数汇总(1)

    //俗话说:好记性不如烂笔头 //用到opencv 中的函数时往往会一时记不起这个函数的具体参数怎么设置,故在此将常用函数做一汇总: Mat srcImage = imread("C:/Us ...

  6. android中的通信机制总结

      第一种:使用handler来进行通信   handler 大家可以把它想象成主线程(UI线程)的一个子线程,它可以给主线程(UI线程)发送数据从而更新主线程(UI线程)的UI与逻辑,handler ...

  7. jsp 颜色和表格控制

    表格控制: table{table-layout:fixed; word-wrap:break-word; word-break:break-all;} 颜色列表:

  8. libuv里的几个缺陷

    libuv是node.js使用的基础库,主要包括主循环,文件和网络接口.虽然libuv是为node.js而生的,但它本身是一个独立的库,加上使用简单方便,所以在node.js之外也有不少人使用.最近整 ...

  9. Event 讲解

    应用场景:某件事发生时,需要采取多步的动作,此时就用到了 使用方法:创建event方法一,使用命令 make:event  生成事件在app/Events目录下,命令make:listener 生成监 ...

  10. Js作用域链及变量作用域

    要理解变量的作用域范围就得先理解作用域链 用var关键字声明一个变量时,就是为该变量所在的对象添加了一个属性. 作用域链:由于js的变量都是对象的属性,而该对象可能又是其它对象的属性,而所有的对象都是 ...