1. 程式人生 > >NOIP 2013 day2

NOIP 2013 day2

`` ans mes tdi display using str top AI

tags:

  • 模擬
  • 貪心
  • 搜索
  • 動態規劃
    categories:
  • 信息學競賽
  • 總結

積木大賽
花匠
華容道

積木大賽

Solution

  發現如果一段先單調上升然後在單調下降, 那麽這一塊的代價是最高的減去前面已經鋪好的, 例如

6 5 6 7 8 9 8 7 6 5

需要先先鋪6 5代價是6, 然後鋪67898765, 代價是9-5.
  根據這個這個就是記錄一個已經鋪好的最大值, 然後如果比已經鋪好的大就加入答案並且更新已經鋪好的.

Code

#include<cstdio>
int main(){
    int n,h,l,a;
    scanf("%d"
,&n); for(int i=0,l=a=0;i<n;++i){ scanf("%d",&h); if(h>l)a+=h-l; l=h; } printf("%d",a); return 0; }

花匠

Solution

  發現實際上是求最長波動子序列, 然後實際上可以用dp做, 但是不如找一下其他的性質, 會發現數列可以表示成下面的形式.
\[ \nearrow \searrow \nearrow \searrow \nearrow \searrow \nearrow \searrow \cdots \]


然後只需要取連續下降子序列中的最大值和連續上升子序列中的最小值.寫的非常草率.

Code

#include<cstdio>
#include<stack>
std::stack<int>que;

int main(){
    int n,h,l;
    scanf("%d",&n);
    for(int i=0;i<n;++i){
        scanf("%d",&h);
        if(que.size()&&h==que.top())continue;
        if
(que.empty())que.push(h); else if(que.size()==1){ if(h==que.top())continue; l=h>que.top();que.push(h); } else if(l){ if(h>que.top()) que.pop(), que.push(h); else que.push(h),l^=1; } else { if(h<que.top()) que.pop(),que.push(h); else que.push(h),l^=1; } } printf("%d\n",que.size()); return 0; }

華容道

Solution

  • bfs, 用空格的位置和目標棋子的位置當狀態, 可以得到70分.
  • bfs出空白格子到每個格子各個方向的路程, 求出最短路.

    Code

    70分做法
    ```c++

    include

    include

    include

    include

    define N 35

include

using namespace std;

struct Graph{
int sx,ox,sy,oy;
Graph(){};
Graph(int s){scanf("%d%d%d%d",&ox,&oy,&sx,&sy);}
Graph(int a,int b,int c,int d){
sx=a,sy=b,ox=c,oy=d;
}
void print(){
printf("Graph: %d %d %d %d\n",sx,sy,ox,oy);
}
};

int dx[9]={0,0,1,-1};
int dy[9]={1,-1,0,0};
int vis[N][N][N][N];
int ti[N][N][N][N];
int n,m,q,ans;
int G[N][N];
Graph start;
int tx,ty;
int tot;

bool check(int x,int y){
if(!G[x][y])return false;
if(x<1||x>n||y<1||y>m)return false;return true;
}

int main(){
int x,y,xx,yy;
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
scanf("%d",&G[i][j]);
while(q--){
memset(vis,false,sizeof(vis));
start=Graph(true);
scanf("%d%d",&tx,&ty);
if(start.sx==tx&&start.sy==ty){
printf("0\n");
continue;
}
ti[start.sx][start.sy][start.ox][start.oy]=0;
std::queueque;
que.push(start);bool flag=false;
while(!que.empty()){
Graph now=que.front(),nxt;que.pop();
for(int i=0;i<4;++i){
nxt=now,xx=now.ox+dx[i],yy=now.oy+dy[i];
if(!check(xx,yy))continue;
x=now.sx,y=now.sy;
if(xx==x&&yy==y)x=now.ox,y=now.oy;
if(vis[x][y][xx][yy])continue;
nxt=(Graph){x,y,xx,yy};
// nxt.print();
ti[x][y][xx][yy]=ti[now.sx][now.sy][now.ox][now.oy]+1;
if(x==tx&&y==ty){
flag=true,ans=ti[x][y][xx][yy];
break;
}
vis[x][y][xx][yy]=true;
que.push(nxt);
}
if(flag)break;
}
if(flag)printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}
```

NOIP 2013 day2