【noip2013】【提高组】【Day2】【解题报告】
来源:互联网 发布:淘宝加入购物车怎么买 编辑:程序博客网 时间:2024/05/18 01:16
T1:积木大赛
题目链接:http://codevs.cn/problem/3288/
题解:可以发现如果后面一个格子比前面一个格子高,那么高出来的那块一定要单独处理。
所以只要把后一个积木和前一个积木的高度差累加进答案再加上第一块积木的高度即可。
复杂度O(n);
代码:
#include<iostream>#include<cstdio>#define N 100010using namespace std;int h[N],ans,minn(99999999),s[N],n;int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) {scanf("%d",&h[i]);} for (int i=1;i<=n;i++){ if (h[i]>h[i-1]) ans+=h[i]-h[i-1]; } cout<<ans<<endl; }
T2:花匠
题目链接:http://codevs.cn/problem/3289/
题解:首先O(n^2)的dp还是很简单的
设f[i][1]表示到i结束,最后两盆花之间的趋势是上升的最大长度。
f[i][0]表示到i结束,最后两盆花之间的趋势是下降的最大长度。
显然
f[i][1]=max(f[j][0]+1,f[i][1])(h[j]<h[i]);
f[i][0]=max(f[j][1]+1,f[i][0])(h[j]>h[i]);
因为是取最大值,所以我们用树状数组优化一下就可以通过了。
复杂度O(n*logn)
代码:
#include<iostream>#include<cstdio>#define N 100010using namespace std;int f[N][2],h[N],ans,n,c1[N*10],c2[N*10],maxx;void add(int c[],int x,int v){for (int i=x;i<=maxx+1;i+=(i&(-i))) c[i]=max(c[i],v);}int query(int c[],int x){ int ans(0);for (int i=x;i;i-=(i&(-i))) ans=max(ans,c[i]); return ans;}int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) {scanf("%d",&h[i]);maxx=max(maxx,++h[i]);} maxx++;add(c1,h[1],1);add(c2,maxx-h[1],1); for (int i=2;i<=n;i++){ f[i][1]=query(c1,h[i]-1)+1;f[i][0]=query(c2,maxx-h[i]-1)+1; add(c2,maxx-h[i],f[i][1]);add(c1,h[i],f[i][0]); ans=max(ans,max(f[i][1],f[i][0])); } cout<<ans<<endl;}
T3:华容道
题目链接:http://codevs.cn/problem/3290/
题解:这个题还是比较麻烦的。
首先暴力bfs就可以通过前60%的数据.
对于100%的数据。
我们预处理一下p[x][y][k][h]表示当前格子在(x,y),空白格子在和它相邻的k方向,当前格子要往h方向移动1格的最小步数。
这个东西显然可以广搜.复杂度O(n^4);
然后我们把[x][y][k]作为状态,首先把空白格子bfs到起始格子的上下左右四个方向作为初始状态。
考虑跑最短路。状态[x][y][k]显然可以更新到[x+dx[i]][y+dy[i]][k'],k'是i的反向。
设目标格子为(tx,ty),
最后答案在[tx][ty][0],[tx][ty][1],[tx][ty][2],[tx][ty][3]中取最小值即可.
最终复杂度O(n^4+k*n^2)
代码:
#include<iostream>#include<cstdio>#include<cstring>#define INF 707406378using namespace std;int n,m,q,ex,ey,sx,sy,tx,ty,map[50][50],p[50][50][5][5];int dx[4]={0,0,-1,1},dy[4]={-1,1,0,0},l[1000000][4],dis[50][50],d[50][50][4];bool f[50][50][5];int bfs(int x,int y,int xx,int yy){ if (!map[x][y]||!map[xx][yy]) return INF; memset(dis,127/3,sizeof(dis)); int h=0,t=1;l[t][1]=x;l[t][2]=y;dis[x][y]=0; while (h<t){ int a=l[++h][1],b=l[h][2];if (a==xx&&b==yy) return dis[a][b];for (int i=0;i<4;i++){ int aa=a+dx[i],bb=b+dy[i]; if (aa>0&&aa<=n&&bb>0&&bb<=m&&dis[aa][bb]==INF&&map[aa][bb]){ dis[aa][bb]=dis[a][b]+1;l[++t][1]=aa;l[t][2]=bb; }} }return INF;}int spfa(){ int h(0),t(0),ans(INF);memset(f,0,sizeof(f)); for (int i=0;i<=4;i++)if (d[sx][sy][i]!=INF){ l[++t][1]=sx;l[t][2]=sy;l[t][3]=i; f[sx][sy][i]=true; } while (h<t){ int x=l[++h][1],y=l[h][2],k=l[h][3];f[x][y][k]=false;for (int i=0;i<4;i++) if (d[x+dx[i]][y+dy[i]][i^1]>d[x][y][k]+p[x][y][k][i]+1&&map[x+dx[i]][y+dy[i]]){ d[x+dx[i]][y+dy[i]][i^1]=d[x][y][k]+p[x][y][k][i]+1; if (!f[x+dx[i]][y+dy[i]][i^1]){ l[++t][1]=x+dx[i];l[t][2]=y+dy[i];l[t][3]=i^1; f[x+dx[i]][y+dy[i]][i^1]=true; } } } for (int i=0;i<4;i++) ans=min(ans,d[tx][ty][i]); if (ans==INF) return -1;else return ans;}void cal(int ex,int ey,int sx,int sy,int tx,int ty){ if (!map[ex][ey]||!map[sx][sy]||!map[tx][ty]) {printf("-1\n");return;}; if (sx==tx&&sy==ty){printf("0\n");return;} memset(d,127/3,sizeof(d));map[sx][sy]=0; for (int i=0;i<4;i++) d[sx][sy][i]=bfs(ex,ey,sx+dx[i],sy+dy[i]); map[sx][sy]=1;printf("%d\n",spfa());}void pre(){ for (int i=1;i<=n;i++) for (int j=1;j<=m;j++){ int t=map[i][j];map[i][j]=0; for (int k=0;k<4;k++) for (int h=0;h<4;h++) p[i][j][k][h]=bfs(i+dx[k],j+dy[k],i+dx[h],j+dy[h]); map[i][j]=t; }}int main(){ scanf("%d%d%d",&n,&m,&q); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&map[i][j]); pre(); for (int i=1;i<=q;i++){ scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);cal(ex,ey,sx,sy,tx,ty); }}
- 【noip2013】【提高组】【Day2】【解题报告】
- NOIP2013提高组Day2 华容道 解题报告
- 2016.7.12 NOIP2013提高组 day2解题报告(未完成版)
- NOIP2013提高组Day2
- 【扩散】【福利】NOIp2013提高组解题报告
- 【NOIP2013】【提高组】【Day1】【解题报告】
- NOIP2013提高组Day1 解题报告
- NOIP2013 提高组复赛解题报告
- 【noip2014提高组】【Day2】【解题报告】
- NOIP 2015 提高组 day2 解题报告
- 【NOIP2013提高组day2】华容道
- 【NOIP2013提高组day2】华容道
- Noip2013提高组day2 花匠
- NOIP2013提高组复赛 转圈游戏 解题报告
- NOIP2013提高组复赛 火柴排队 解题报告
- NOIP2015提高组Day2 第二题 子串 解题报告
- [解题报告] NOIP 2014 提高组Day2试题
- 【NOIP2013提高组day2】【JZOJ 3537】华容道
- java设计模式_观察者Observer(一)
- 2.8 Loop Detection
- 超全!iOS 面试题汇总
- Spritekit中如何判断触摸点击的精灵
- 悟语 KISS 简单至上 keep it simple stupid
- 【noip2013】【提高组】【Day2】【解题报告】
- 百度富媒体编辑器 使用
- Java学习笔记1——关于Scanner类中nextDouble、nextInt、……等方法与nextLine方法联用的问题
- Java:String和Date、Timestamp之间的转换
- 三层架构实战篇—系统登录实例
- 三层架构(我的理解及详细分析)
- 获取android应用或apk的md5指纹方法
- 什么是用户画像?金融行业大数据用户画像实践 [
- bzoj-2259 新型计算机