您的位置:首页 > 其它

NOIP模拟题 10.31

2016-10-31 17:27 295 查看

T1 Mushroom的序列

【问题描述】

Mushroom手中有n个数排成一排,现在Mushroom想取一个连续的子序列,使得这个子序列满足:最多只改变一个数,使得这个连续的子序列是严格上升子序列,Mushroom想知道这个序列的最长长度是多少。

【输入格式】

第一行一个整数n,表示有n个数。

第二行为n个数。

【输出格式】

一个数,为最长长度。

【输入样例】

6

7 2 3 1 5 6

【输出样例】

5

【样例解释】

选择第2个数到第6个数,把1改变成4即可。

【数据范围】

对于30%的数据,n<=10

对于60%的数据,n<=1000

对于100%的数据,n<=100000

这道题可以直接从头到尾扫一遍,判断情况。我用的是两边扫一遍,然后判断是否可以改。水题,不说了。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int a[100002],f[100002],g[100002],ans;
inline int read()
{
static int r,sign;
static char c;
r=0,sign=1;
do c=getchar();while(c!='-'&&(c<'0'||c>'9'));
if(c=='-')sign=-1,c=getchar();
while(c>='0'&&c<='9')r=r*10+(int)(c-'0'),c=getchar();
return sign*r;
}
int main()
{
freopen("seq.in","r",stdin);
freopen("seq.out","w",stdout);
int n=read();
for(int i=1;i<=n;i++)
a[i]=read();
f[1]=1;g
=1;
for(int i=2;i<=n;i++)
{
if(a[i]>a[i-1])
f[i]=f[i-1]+1;
else f[i]=1;
}
for(int i=n-1;i>=1;i--)
{
if(a[i]<a[i+1])
g[i]=g[i+1]+1;
else g[i]=1;
}
for(int i=1;i<=n;i++)
{
if(i-f[i]>=1)
ans=max(ans,f[i]+1);
else ans=max(ans,f[i]);
if(i+g[i]<=n)
ans=max(ans,g[i]+1);
else ans=max(ans,g[i]);
}
for(int i=1;i<=n-2;i++)
if(a[i]<=a[i+2]-2)
ans=max(ans,1+f[i]+g[i+2]);
printf("%d",ans);
return 0;
}


T2 Mushroom的区间

【题目描述】

Mushroom有一行数,初始时全部是0。现在Mushroom有m个区间[L,R],他希望用以下操作得到新的序列。

从m个给定区间中选择一个区间[s,t],把区间中的数对应元素全部翻转。(0变1,1变0)

请告诉Mushroom他能得到多少区间。(模10^9+7)

【输入格式】

第一行包含两个整数n,m。表示n个数和m个区间。

接下来m行是所表示的区间。

【输出格式】

一个整数,表示能得到的区间数。

【样例输入】

3 3

1 1

2 2

3 3

【样例输出】

8

【数据范围】

对于30%的数据,n,m<=20

对于60%的数据,n,m<=100

对于100%的数据,n,m<=100000

【样例解释】

每个位置都可以单个修改,所以有8种可能。

朴素想法是用二进制数保存状态,但貌似30%都没法过,因为20的阶乘还是蛮大的,但数据水…过了前三组…

有人用搜索A了。首先答案是2^m,考虑到只有可能大区间包含小区间,如果一个大区间可以由几个小区间组成,那么m就要减1。将每个区间左开右闭或者坐闭右开来储存,将结构体按区间长度来排序,每枚举一个区间dfs区间的开头,如果搜到的边界搜过,m-=1。本来应该是过不完的,但数据水…

正解思想如上,但是妙用并查集,将区间开头结尾用并查集储存起来,每枚举一个区间,如果区间两端祖先相同,m-=1。

代码:

#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
int x,y,n,m,f[200005],ans=1;
inline int read()
{
static int r,sign;static char c;
r=0,sign=1;
do c=getchar();while(c!='-'&&(c<'0'||c>'9'));
if(c=='-')sign=-1,c=getchar();
while(c>='0'&&c<='9')r=r*10+(int)(c-'0'),c=getchar();
return sign*r;
}
int find(int x)
{
if(f[x]==x)
return x;
return f[x]=find(f[x]);
}
int main ()
{
freopen("seg.in","r",stdin);
freopen("seg.out","w",stdout);
n=read();m=read();
for(int i=0;i<=n;i++)
f[i]=i;
for(int i=1;i<=m;i++)
{
x=read();y=read();
int fx=find(x-1);
int fy=find(y);
if(fx!=fy)
{
ans=(ans<<1)%mod;
f[fx]=fy;
}
}
printf("%d\n",ans);
return 0;
}


T3 来自风平浪静的明天

【题目描述】

冬眠了五年,光终于从梦中醒来。

千咲、要,大家都在。

隐约记得“昨天”的海船祭,爱花意外成为贡女,沉入海底。

海面冰封,却有丝丝暖流在冰面之下涌动。

此时,爱花沉睡在祭海女神的墓地。她的胞衣在一点点脱落,化作一簇簇暖流,夹杂着她的感情,向海面上涌去。

爱花,你在哪里?

五年之后,纺已经成为海洋学研究科的大学生。

在纺的帮助下,光得知了海面下海流的情况。

纺告诉光,暖流一旦产生,就会不断地向四周扩散,直到遇到海中的岩石。

红腹海牛,快告诉光,爱花在哪里。

纺帮你绘制了一张海流情况图,长度为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 出发,在碰到 B 之前能够将所有的 H 遍历,这个 H 就是答案。

朴素想法用bfs搜就是。数据水,只有倒数第二个点要T…

正解没有写,使用dp做的。

bfs:

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int xx,yy;
}gg[90003];
int x[4]={0,0,1,-1},y[4]={1,-1,0,0};
char map[302][302];
int bcnt,n,m,num[90003][2],ord[90003],tot;
bool judge[302][302];
bool bfs(int i,int j)
{
ord[1]=1;
tot=1;
queue<node>q;
node o;
o.xx=i;
o.yy=j;
q.push(o);
int step=1,coun=0,pre=0,time=0x7f7f7f7f;
bool bbbb=false;
while(!q.empty())
{
node u=q.front();
q.pop();
if(pre==ord[tot])
{
bbbb=false;
ord[++tot]=coun;
coun=0;
pre=0;
}
if(step==bcnt)
return true;
pre++;
for(int k=0;k<=3;k++)
{
int ox=u.xx+x[k],oy=u.yy+y[k];
if(ox>=1&&ox<=n&&oy>=1&&oy<=m&&!judge[ox][oy])
{
if(map[ox][oy]=='H')
{
if(tot-1>time)
return false;
node t;t.xx=ox;t.yy=oy;q.push(t);
step++;coun++;
judge[ox][oy]=true;
}
else if(map[ox][oy]=='B')
time=tot-1;
}
}
}
if(step==bcnt)
return true;
}
int main()
{
freopen("calm.in","r",stdin);
freopen("calm.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
getchar();
for(int j=1;j<=n;j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='H')
{
num[++bcnt][0]=i;
num[bcnt][1]=j;
}
}
}
for(int i=1;i<=bcnt;i++)
{
judge[num[i][0]][num[i][1]]=true;
int l=num[i][0],r=num[i][1];
if(bfs(num[i][0],num[i][1]))
{
printf("%d %d",num[i][0],num[i][1]);
return 0;
}
memset(judge,false,sizeof judge);
memset(ord,0,sizeof ord);
}
printf("-1");
return 0;
}


标答正解:

#include <cstdio>
#include <iostream>
#define INF 300
#include <algorithm>
using namespace std;
char Map[INF+1][INF+1];
bool Find[2*INF+1][INF+1][INF+1];
bool Flow[2*INF+1][INF+1][INF+1];
int N,M;
bool LoveFlower(int Deep,int X,int Y)
{
if (0==X) return true;
if (0==Y) return true;
if (N+1==X) return true;
if (M+1==Y) return true;
if (Map[X][Y]!='H') return true;
if (Find[Deep][X][Y]) return Flow[Deep][X][Y];
if (0==Deep)
{
Find[Deep][X][Y]=true;
Flow[Deep][X][Y]=(Map[X][Y]=='H');
return Flow[Deep][X][Y];
}
if ('B'==Map[X-1][Y]||'B'==Map[X+1][Y]||'B'==Map[X][Y-1]||'B'==Map[X][Y+1])
{
Find[Deep][X][Y]=true;
Flow[Deep][X][Y]=false;
return Flow[Deep][X][Y];
}
Find[Deep][X][Y]=true;
Flow[Deep][X][Y]=LoveFlower(Deep-1,X-1,Y)&&LoveFlower(Deep-1,X+1,Y)&&LoveFlower(Deep-1,X,Y-1)&&LoveFlower(Deep-1,X,Y+1);
return Flow[Deep][X][Y];
}
char T[INF+1];
int main()
{
freopen("Calm.in","r",stdin);
freopen("Calm.out","w",stdout);
scanf("%d%d",&N,&M);
for (int i=1;i<=N;i++)
{
scanf("%s",T);
for (int j=1;j<=M;j++)
Map[i][j]=T[j-1];
}
for (int i=1;i<=N+M;i++)
for (int j=1;j<=N;j++)
for (int k=1;k<=M;k++)
if (Map[j][k]=='H')
LoveFlower(i,j,k);
for (int i=N+M;i>=1;i--)
for (int j=1;j<=N;j++)
for (int k=1;k<=M;k++)
if (Flow[i][j][k])
{
cout<<j<<" "<<k<<'\n';
return 0;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  模拟题