NOIP2013 DAY2题解
DAY2
T1积木大赛
题目大意:每次可以选区间[l,r]加1,最少选几次,让每个位置有
它应有的高度。
题解:O(n)扫一遍就好了。后一个比前一个的高度低,那么前一个已经把它覆盖了,
如果高那么就需要+1了。
代码:
#include<iostream>
#include<cstdio>
#define maxn 100009
using namespace std; int n,x,pre,ans; void read(int &x){
char ch=getchar();int f=;x=;
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';
x*=f;
} int main(){
freopen("block.in","r",stdin);
freopen("block.out","w",stdout);
read(n);
for(int i=;i<=n;i++){
read(x);
if(x>pre)ans=ans+x-pre;
pre=x;
}
printf("%d\n",ans);
fclose(stdin);fclose(stdout);
return ;
}
AC
T2花匠
题目大意:求最长波动子序列
题解:贪心
暴力dp[i][1/0][1/0]表示到第i个数作为波峰(1)或波谷(0)选(1)还是不选(0)的最长长度
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 100008
using namespace std; int n,h[maxn],dp[maxn][][]; void read(int &x){
char ch=getchar();x=;int f=;
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';
x=x*f;
} int main(){
read(n);
for(int i=;i<=n;i++)read(h[i]);
dp[][][]=dp[][][]=;
for(int i=;i<=n;i++){
for(int j=;j<i;j++){
if(h[i]>h[j])dp[i][][]=max(dp[i][][],dp[j][][]+);
if(h[i]<h[j])dp[i][][]=max(dp[i][][],dp[j][][]+);
dp[i][][]=dp[i][][]=max(max(dp[j][][],dp[j][][]),max(dp[j][][],dp[j][][]));
}
}
printf("%d\n",max(max(dp[n][][],dp[n][][]),max(dp[n][][],dp[n][][])));
return ;
}
70
这不跟昨天湖南的题一样么。
对于 5 4 3 2 9
5 2 9,4 2 9,3 2 9,好像没什么区别。那么连续递减的5 4 3 2就可以看成一个数了。
以一个数为大的和小的分别扫一遍就好。
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 100008
using namespace std; int ans,ret,cur,flag,n,h[maxn]; void read(int &x){
char ch=getchar();x=;int f=;
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';
x=x*f;
} int main(){
freopen("flower.in","r",stdin);
freopen("flower.out","w",stdout);
read(n);
for(int i=;i<=n;i++)read(h[i]);
cur=h[];ans=;
for(int i=;i<=n;i++){
if(flag){
if(h[i]<cur)flag=,ans++,cur=h[i];
else cur=max(cur,h[i]);
}else{
if(h[i]>cur)flag=,ans++,cur=h[i];
else cur=min(cur,h[i]);
}
}
cur=h[];ret=;flag=;
for(int i=;i<=n;i++){
if(flag){
if(h[i]>cur)flag=,ret++,cur=h[i];
else cur=min(cur,h[i]);
}else{
if(h[i]<cur)flag=,ret++,cur=h[i];
else cur=max(cur,h[i]);
}
}
ans=max(ans,ret);
printf("%d\n",ans);
fclose(stdin);fclose(stdout);
return ;
}
AC
一个多月前我做的...似乎是看了就是看了题解...
#include<iostream>
#include<cstdio>
using namespace std;
int n,pre,now,r=,d=;
int main()
{
scanf("%d",&n);
scanf("%d",&pre);//当前这盆花前面那盆花的高度,初始为第一盆花的高度。
for(int i=;i<n;i++)
{
scanf("%d",&now);
if(now>pre)r=max(r,d+);//当前这盆花高度大于前面那盆花高度
if(now<pre)d=max(d,r+);//说明现在是上升序列,就要求出到Now这个花盆且波动为
pre=now; //上升的最优解,就从原来求出的最后波动为上升的最优解,
} //(也就是说此时当前这盆花不加入之前最优解,移走)
printf("%d",max(r,d));//和从最后波动为下降的最优解+1选取最优值(不移走)。
return ;
}
AC
T3华容道
题目大意:一个n*m的矩阵,有n*m-1个棋子。1表示该棋子能移动,0表示不能。
给出指定位置和目标位置。求最少几步能利用空白格子将指定位置棋子移到目标位置。
题解:
dfs 5分...怀疑人生
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 100000000
using namespace std; int n,m,q,x,cnt,ans;
int ex,ey,sx,sy,tx,ty;
int t[][],tmp[][],vis[][];
int mx[]={,,-,},
my[]={-,,,}; void read(int &x){
char ch=getchar();x=;int f=;
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';
x=x*f;
} void dfs(int ex,int ey,int sx,int sy,int tx,int ty,int prex,int prey,int ste){
if(ex==tx&&ey==ty&&abs(sx-ex)+abs(sy-ey)<=){
ans=min(ans,ste+);
return;
}
for(int i=;i<;i++){
int xx=ex+mx[i],yy=ey+my[i];
if(xx>=&&xx<=n&&yy>=&&yy<=m&&t[xx][yy]&&(xx!=prex||yy!=prey)&&!vis[xx][yy]){
vis[xx][yy]=true;
if(xx==sx&&yy==sy){
dfs(xx,yy,ex,ey,tx,ty,ex,ey,ste+);
}else dfs(xx,yy,sx,sy,tx,ty,ex,ey,ste+);
}
}
} int main(){
// freopen("puzzle.in","r",stdin);
// freopen("puzzle.out","w",stdout);
read(n);read(m);read(q);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
read(t[i][j]);
for(int i=;i<=q;i++){
cnt=;ans=inf;
memset(vis,,sizeof(vis));
read(ex);read(ey);//空白格子
vis[ex][ey]=true;
read(sx);read(sy);//指定棋子
read(tx);read(ty);//目标位置
if(sx==tx&&sy==ty){
printf("0\n");
continue;
}
dfs(ex,ey,sx,sy,tx,ty,,,);
if(ans==inf)printf("-1\n");
else printf("%d\n",ans);
}
// fclose(stdin);fclose(stdout);
return ;
}
5
bfs 70 其实考试时开始写的bfs。发现不会记录状态。
看了题解算来只需要记录空白格子和指定棋子的位置就好了。
时间复杂度O(q*(nm)^2)
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std; int ans,n,m,qx,tx,ty;
int t[][],vis[][][][];
int mx[]={,,,-},
my[]={-,,,};
struct Node{
int ex,ey,sx,sy,ste;
}now;
queue<Node>q; void read(int &x){
char ch=getchar();x=;int f=;
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';
x=x*f;
} void BFS(){
memset(vis,,sizeof(vis));
Node tmp,cur;
vis[now.sx][now.sy][now.ex][now.ey]=true;
while(!q.empty())q.pop();q.push(now);
while(!q.empty()){
cur=q.front();q.pop();
if(cur.sx==tx&&cur.sy==ty){
ans=cur.ste;
return;
}
for(int i=;i<;i++){
tmp=cur;
int xx=tmp.ex+mx[i],yy=tmp.ey+my[i];
if(!t[xx][yy]||xx<||xx>n||yy<||yy>m)continue;
if(xx==tmp.sx&&yy==tmp.sy)tmp.sx=tmp.ex,tmp.sy=tmp.ey;
tmp.ex=xx;tmp.ey=yy;tmp.ste=cur.ste+;
if(!vis[tmp.sx][tmp.sy][tmp.ex][tmp.ey]){
vis[tmp.sx][tmp.sy][tmp.ex][tmp.ey]=true;
q.push(tmp);
}
}
}
} int main(){
read(n);read(m);read(qx);
for(int i=;i<=n;i++) for(int j=;j<=m;j++) read(t[i][j]);
for(;qx;qx--){
read(now.ex);read(now.ey);read(now.sx);read(now.sy);read(tx);read(ty);
now.ste=;ans=n*m;
BFS();
if(ans!=n*m)printf("%d\n",ans);
else printf("-1\n");
}
return ;
}
70
正解..搜索+最短路。傻逼错误毁我青春...从下午写到现在...
我还是单独开个随笔讲这个题吧。邪王真眼
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define maxn 5000
#define inf 2147483647 int n,m,qx,sumedge,ans,ex,ey,sx,sy,tx,ty,p;
int map[][],pre_dis[][],head[maxn],vis[maxn],dis[maxn];
int mx[]={-,,,},
my[]={,,,-};
struct Node{
int x,y;
}cur,nxt;
queue<Node>q;
queue<int>qn; struct Edge{
int x,y,z,nxt;
Edge(int x=,int y=,int z=,int nxt=):
x(x),y(y),z(z),nxt(nxt){}
}edge[maxn]; void add(int x,int y,int z){
edge[++sumedge]=Edge(x,y,z,head[x]);
head[x]=sumedge;
} int get_id(int i,int j){
return (i-)*m*+(j-)*;
} void bfs(int ex,int ey,int sx,int sy,int d){
memset(pre_dis,-,sizeof(pre_dis));
pre_dis[ex][ey]=;pre_dis[sx][sy]=;
Node now,nxt;now.x=ex;now.y=ey;
while(!q.empty())q.pop();
q.push(now);
while(!q.empty()){
now=q.front();q.pop();
int x=now.x,y=now.y;
for(int i=;i<;i++){
int xx=x+mx[i],yy=y+my[i];
if(xx<||xx>n||yy<||yy>m||!map[xx][yy]||pre_dis[xx][yy]!=-)continue;
pre_dis[xx][yy]=pre_dis[x][y]+;
nxt.x=xx;nxt.y=yy;
q.push(nxt);
}
}
if(d==)return;
int id=get_id(sx,sy);
for(int i=;i<;i++)
if(pre_dis[sx+mx[i]][sy+my[i]]>)
add(id+d,id+i,pre_dis[sx+mx[i]][sy+my[i]]);
add(id+d,get_id(ex,ey)+(d+)%,);
} void spfa(int sx,int sy){
memset(dis,-,sizeof(dis));
memset(vis,,sizeof(vis));
while(!qn.empty())qn.pop();
int id=get_id(sx,sy);
for(int i=;i<;i++)
if(pre_dis[sx+mx[i]][sy+my[i]]!=-){
dis[id+i]=pre_dis[sx+mx[i]][sy+my[i]];
qn.push(id+i);
}
while(!qn.empty()){
int cur=qn.front();qn.pop();vis[cur]=false;
for(int i=head[cur];i;i=edge[i].nxt){
int v=edge[i].y;
if(dis[v]>dis[cur]+edge[i].z||dis[v]==-){
dis[v]=dis[cur]+edge[i].z;
if(!vis[v]){
vis[v]=true;
qn.push(v);
}
}
}
}
} int main(){
scanf("%d%d%d",&n,&m,&qx);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
scanf("%d",&map[i][j]);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(map[i][j]){
if(map[i-][j])bfs(i-,j,i,j,);
if(map[i][j+])bfs(i,j+,i,j,);
if(map[i+][j])bfs(i+,j,i,j,);
if(map[i][j-])bfs(i,j-,i,j,);
}
for(int i=;i<=qx;i++){
scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
if(sx==tx&&sy==ty){
printf("0\n");
continue;
}
bfs(ex,ey,sx,sy,);
ans=inf;
spfa(sx,sy);
int id=get_id(tx,ty);
for(int j=;j<;j++)
if(dis[id+j]!=-)ans=min(ans,dis[id+j]);
if(ans==inf) ans=-;
printf("%d\n",ans);
}
return ;
}
AC
NOIP2013 DAY2题解的更多相关文章
- 二模Day2题解
小明搬家 题目描述 小明要搬家了,大家都来帮忙. 小明现在住在第N楼,总共K个人要把X个大箱子搬上N楼. 最开始X个箱子都在1楼,但是经过一段混乱的搬运已经乱掉了.最后大家发现这样混乱地搬运过程效率太 ...
- 【NOIP2012】DAY1+DAY2题解
不贴代码的原因是我的代码在初中机房.忘记带过来了. DAY 1 T1随便搞,但是字符串相关的题我经常犯蠢 T2 一个结论题,OAO但是需要高精度写. 具体就是按左手的数除右手的数(还是怎么的来着)排个 ...
- [NOIP2013]华容道 题解(搜索)
[NOIP2013]华容道 [题目描述] 这道题根据小时候玩华容道不靠谱的经验还以为是并查集,果断扑街.考后想想也是,数据这么小一定有他的道理. 首先由于是最小步数,所以BFS没跑了.那么我们大可把这 ...
- [NOIP2013]华容道 题解
[NOIP2013]华容道 首先是一种比较显然的做法. 整个棋盘,除了起点,终点和空格,其他的方块是等价的. 对于终点,它始终不会变化,如果搜到终点结束搜索即可,所以我们不需要考虑终点. 所以需要考虑 ...
- CCF统一省选 Day2 题解
此题解是教练给我的作业,AK了本场比赛的人,以及认为题目简单的人可以不必看 T1 算法一 暴力枚举对信号站顺序的不同排列,然后对代价取\(\min\)即可. 时间复杂度\(O(m! \cdot n)\ ...
- 【NOIP2014】DAY2题解+代码
T1 傻逼题……不想写贴昨年代码了. 总之随便怎么搞都能过. 15年的DAY2T1怎么那么毒瘤真是越活越倒退] #include <iostream> #include <fstre ...
- NOIP[2015] Day2题解
问题 A: 跳石头 时间限制: 1 Sec 内存限制: 128 MB 题目描述 一年一度的"跳石头"比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石. ...
- 【2018暑假集训模拟一】Day2题解
T1 园艺工人的求助 [题目描述]终于,在一段繁忙的训练之后,到了NOIP 的举办的时候.同学们坐上了大巴车,享受着沿途的风光,讨论着未解决的问题,憧憬着NOIP 赛场上切题的样子.很快,大巴车到了大 ...
- NOIP2013 Day2
1.积木大赛 https://www.luogu.org/problemnew/show/1969 这道题在考试时暴力得比较麻烦,导致只得了80分,t了两个点. 思路为寻找一个区间内高度大于0的最低点 ...
随机推荐
- 介绍Web项目中用到的几款表单验证插件
第一个插件 jqueryvalidation 官网地址:http://jqueryvalidation.org/ 第二个插件 nice Validator 官网地址: http://niceue.co ...
- redis主从、集群、哨兵
redis的主从.集群.哨兵 参考: https://blog.csdn.net/robertohuang/article/details/70741575 https://blog.csdn.net ...
- UVA 10288 Coupons (概率)
题意:有n种纸片无限张,随机抽取,问平均情况下抽多少张可以保证抽中所有类型的纸片 题解:假设自己手上有k张,抽中已经抽过的概率为 s=k/n:那抽中下一张没被抽过的纸片概率为 (再抽一张中,两张中,三 ...
- java.lang.IllegalArgumentException异常处理的一种方法
我遇到的问题 用spring注解来加载bean,都是一个简单的了,但是还是报了这样一个错java.lang.IllegalArgumentException 网上查了一下,说是jdk版本要1.7的,然 ...
- 未来简史之数据主义(Dataism)
https://www.jianshu.com/p/8147239c9cb0?from=singlemessage junjguo 关注 2017.04.24 22:08* 字数 8116 阅读 31 ...
- SSO 证书配置
ssodev.crt为开发环境证书ssotest.crt为测试环境证书 将证书拷贝到目录:{JDK}\jre\lib\security 其中 {JDK} 是实际安装JDK的位置.然后cmd进入命令窗口 ...
- oracle 子查询详解 in和exists的区别
sql允许多层嵌套,子查询是嵌套在其他查询中的查询.我们可以把子查询当做一张表来看到,即外层语句可以把内嵌的查询结果当做一张表使用. 子查询查询结果有三种情况 不返回查询记录.若子查询不返回记录则主查 ...
- SpringBoot:竟然has no explicit mapping for /error
异常:This application has no explicit mapping for /error, so you are seeing this as a fallback. 出现这个异常 ...
- django-simple-captcha 使用 以及添加动态ajax刷新验证
参考博客:http://blog.csdn.net/tanzuozhev/article/details/50458688?locationNum=2&fps=1 参考博客:http://bl ...
- BusyIndicator using MVVM 忙碌状态指示器的的实现
ViewModel 视图模型 public abstract class ViewModelBase : INotifyPropertyChanged { private bool isbusy; p ...