zoj 1361 | poj 1324

來源:互聯網
上載者:User

題目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=361

BFS。。ZOJ的資料相對poj水了點,直接BFS。就可以過了、這題關鍵是判重,把蛇頭座標和蛇身相對座標表示出來。。在擷取蛇身的相對座標時搞錯了。導致錯了N次。

計算蛇身時,要把蛇頭去掉。也就是l-1,= =!

對於poj的資料,我用的a*過的。。稍微加了一下最佳化。。評估函數為當前步數加上蛇頭到(1,1)的至少應該走的步數。 (單獨) 蛇頭到(1,1)的至少應走的步數的計算,也就是不計算蛇身的位置。那麼直接BFS就可以了。

如果還加上蛇身。效率應該更快。但是我這樣寫簡便一點。

下面是沒最佳化的代碼:

#include<cstdio>#include<queue>#include<cstring>#include<cstdlib>using namespace std;const int maxn =21;int n,m,l,find,ans,move;bool map[maxn][maxn];int dx[]={1,-1,0,0};int dy[]={0,0,1,-1};bool vis[maxn][maxn][1<<14];bool check(int x,int y){   return x>=1&&x<=n&&y>=1&&y<=m;  }struct node{   int head[2],tail[2];   bool map[maxn][maxn];   int step,val;}s_pos;void bfs(){     memset(vis,false,sizeof(vis));     queue<node > q;  q.push(s_pos);     vis[s_pos.head[0]][s_pos.head[1]][ s_pos.val] =true;     while(!q.empty()){         node now = q.front();  q.pop();         if(now.head[0]==1&&now.head[1]==1){             find=1;  ans=now.step;             return ;         }         for(int i=0;i<4;i++){             node next = now;  next.step+=1;             int x=now.head[0]+dx[i];  int y=now.head[1]+dy[i];             if(check(x,y)){                 if(next.map[x][y])  continue;                 next.head[0]=x;  next.head[1]=y;                 next.map[x][y]=true;                 next.map[now.tail[0]][now.tail[1]]=false;                 int t= next.val&3;                 next.tail[0]=now.tail[0]+dx[t];                 next.tail[1]=now.tail[1]+dy[t];                 next.val=next.val>>2;                 int sum=i<<move;                 next.val+=sum;                 if(!vis[x][y][next.val]){                     vis[x][y][next.val]=true;                     q.push(next);                 }             }         }     }}int main(){    int t,x,y,ca=1;    int nx[10],ny[10];    while(scanf("%d%d%d",&n,&m,&l)!=EOF,(n+m+l)){        memset(s_pos.map,false,sizeof(s_pos.map));        memset(map,false,sizeof(map));        s_pos.val=0;  move=((l<<1)-4);        for(int i=0;i<l;i++) {            scanf("%d%d",&x,&y);            nx[i]=x;ny[i]=y;            s_pos.map[x][y]=true;            if(i>0){               for(int j=0;j<4;j++){                   if(x+dx[j]==nx[i-1]&&y+dy[j]==ny[i-1]){                          s_pos.val=(s_pos.val<<2)+j;                          break;                    }               }            }        }        s_pos.head[0]=nx[0],  s_pos.head[1]=ny[0];        s_pos.tail[0]=nx[l-1];s_pos.tail[1]=ny[l-1];        scanf("%d",&t);   s_pos.step=0;        for(int i=0;i<t;i++){            scanf("%d%d",&x,&y);            map[x][y]=true;            s_pos.map[x][y]=true;        }        find=0;   bfs();             printf("Case %d: ",ca++);        if(find){             printf("%d\n",ans);        }        else printf("-1\n");    }    return 0;}

下面是最佳化的代碼:

#include<cstdio>#include<queue>#include<cstring>#include<cstdlib>using namespace std;const int maxn =21;int n,m,l,fond,ans,move,ca;bool map[maxn][maxn];int cnt[maxn][maxn];int dx[]={1,-1,0,0};int dy[]={0,0,1,-1};unsigned char vis[maxn][maxn][1<<14];inline bool check(int x,int y){   return x>=1&&x<=n&&y>=1&&y<=m;  }struct node{   int head[2],tail[2];   bool map[maxn][maxn];   int step,val;   bool operator <(const node &a) const{        return cnt[a.head[0]][a.head[1]]+a.step<cnt[head[0]][head[1]]+step;   }}s_pos;void get_min(){    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cnt[i][j]=1000000;    cnt[1][1]=0;    queue<int > q;q.push(1); q.push(1);    while(!q.empty()){        int x=q.front(); q.pop();int y=q.front();q.pop();        for(int i=0;i<n;i++){            int nx=x+dx[i]; int ny=y+dy[i];            if(check(nx,ny)){                if(map[nx][ny])  continue ;               if(cnt[x][y]+1<cnt[nx][ny]){                   cnt[nx][ny]=cnt[x][y]+1;                   q.push(nx); q.push(ny);               }            }        }    }}void bfs(){     priority_queue<node > q;  q.push(s_pos);     vis[s_pos.head[0]][s_pos.head[1]][ s_pos.val] =true;     while(!q.empty()){         node now = q.top();  q.pop();         if(now.head[0]==1&&now.head[1]==1){             fond=1;  ans=now.step;             return ;         }         for(int i=0;i<4;i++){             node next = now;  next.step+=1;             int x=now.head[0]+dx[i];  int y=now.head[1]+dy[i];             if(check(x,y)){                 if(next.map[x][y])  continue;                 next.head[0]=x;  next.head[1]=y;                 next.map[x][y]=true;                 next.map[now.tail[0]][now.tail[1]]=false;                 int t= next.val&3;                 next.tail[0]=now.tail[0]+dx[t];                 next.tail[1]=now.tail[1]+dy[t];                 next.val=next.val>>2;                 int sum=i<<move;                 next.val+=sum;                 if(vis[x][y][next.val]!=ca){                     vis[x][y][next.val]=ca;                     q.push(next);                 }             }         }     }}int main(){    int t,x,y;    int nx[10],ny[10];    ca=1;    while(scanf("%d%d%d",&n,&m,&l)!=EOF,(n+m+l)){        memset(s_pos.map,false,sizeof(s_pos.map));        memset(map,false,sizeof(map));        s_pos.val=0;  move=((l<<1)-4);        for(int i=0;i<l;i++) {            scanf("%d%d",&x,&y);            nx[i]=x;ny[i]=y;            s_pos.map[x][y]=true;            if(i>0){               for(int j=0;j<4;j++){                   if(x+dx[j]==nx[i-1]&&y+dy[j]==ny[i-1]){                          s_pos.val=(s_pos.val<<2)+j;                          break;                    }               }            }        }        s_pos.head[0]=nx[0],  s_pos.head[1]=ny[0];        s_pos.tail[0]=nx[l-1];s_pos.tail[1]=ny[l-1];        scanf("%d",&t);   s_pos.step=0;        for(int i=0;i<t;i++){            scanf("%d%d",&x,&y);            map[x][y]=true;            s_pos.map[x][y]=true;        }        fond=0;    get_min(); bfs();             printf("Case %d: ",ca++);        if(fond){             printf("%d\n",ans);        }        else printf("-1\n");    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.