zoukankan      html  css  js  c++  java
  • [Usaco2005 Dec]【Knights of Ni 骑士】

    题目描述

    贝茜遇到了一件很麻烦的事:她无意中闯入了森林里的一座城堡,如果她想回家,就必须穿过这片由骑士们守护着的森林。为了能安全地离开,贝茜不得不按照骑士们的要求,在森林寻找一种特殊的灌木并带一棵给他们。

    当然,贝茜想早点离开这可怕的森林,于是她必须尽快完成骑士们给的任务,贝茜随身带着这片森林的地图,地图上的森林被放入了直角坐标系,并按 x,yx,y 轴上的单位长度划分成了 W imes HW×H ( 1 leq W,H leq 10001W,H1000 )块,贝茜在地图上查出了她自己以及骑士们所在的位置,当然地图上也标注了她所需要的灌木生长的区域。某些区域是不能通过的(比如说沼泽地,悬崖,以及食人兔的聚居地)。在没有找到灌木之前,贝茜不能通过骑士们所在的那个区域,为了确保她自己不会迷路,贝茜只向正北、正东、正南、正西四个方向移动(注意,她不会走对角线)。她要走整整一天,才能从某块区域走到与它相邻的那块区域。

    贝茜希望你能帮她计算一下,她最少需要多少天才可脱离这可怕的地方?输入数据保证贝茜一定能完成骑士的任务。

    输入输出格式

    输入格式

    第1行输入2个用空格隔开的整数,即题目中提到的 W,HW,H 。

    接下来输入贝茜持有的地图,每一行用若干个数字代表地图上对应行的地形。第1行描述了地图最北的那一排土地;最后一行描述的则是最南面的。相邻的数字所对应的区域是相邻的。如果地图的宽小于或等于40,那每一行数字恰好对应了地图上的一排土地。如果地图的宽大于40,那每行只会给出40个数字,并且保证除了最后一行的每一行都包含恰好40个数字。没有哪一行描述的区域分布在两个不同的行里。

    地图上的数字所对应的地形:

    0:贝茜可以通过的空地;

    1:由于各种原因而不可通行的区域;

    2:贝茜现在所在的位置;

    3:骑士们的位置;

    4:长着贝茜需要的灌木的土地。

    输出格式

    输出一个正整数,即贝茜最少要花多少天才能完成骑士们给的任务。

    输入输出样例

    输入样例1

    8 4
    4 1 0 0 0 0 1 0
    0 0 0 1 0 1 0 0
    0 2 1 1 3 0 4 0
    0 0 0 4 1 1 1 0
    

      

    输出样例1

    11
    

    解题思路1

      分别以骑士和贝茜为起点广搜,并记录步数(注意以贝茜为起点是不能搜索骑士)。然后循环查找树丛位置,两个相加再与ans取最小值即可。

    题解1

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m,sx,sy,ex,ey,ans=999999+999999;
     4 int mp[1001][1001];//存图 
     5 int bu[1001][1001][2];//记步数,0为贝茜,1为骑士 
     6 struct node{
     7     int x;
     8     int y;
     9 };//坐标 
    10 queue<node> q;
    11 bool flag[1001][1001];//标记 
    12 int dir[4][2]={0,1,0,-1,1,0,-1,0};//四个方向 
    13 void bfs(int x,int y,int mode)
    14 {
    15     q.push((node){x,y});
    16     bu[x][y][mode]=0;//起点0步 
    17     flag[x][y]=true;//标记 
    18     while(!q.empty())
    19     {
    20         node head=q.front();
    21         q.pop();
    22         for(int i=0;i<4;i++)
    23         {
    24             int tx=head.x+dir[i][0];
    25             int ty=head.y+dir[i][1];
    26             if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&!flag[tx][ty]&&mp[tx][ty]!=1&&mp[tx][ty]!=3)//判断出界、骑士、标记(因为以骑士为中心搜,骑士也会打标记,所以3这里没有特判) 
    27             {
    28                 flag[tx][ty]=true;//标记 
    29                 bu[tx][ty][mode]=bu[head.x][head.y][mode]+1;//记录步数 
    30                 q.push((node){tx,ty});//进队列 
    31             }
    32         }
    33     }
    34 }
    35 inline int read(){//快读,不加过不了 
    36     int x=0,f=1;
    37     char ch=getchar();
    38     while(ch<'0'||ch>'9'){
    39         if(ch=='-')
    40             f=-1;
    41         ch=getchar();
    42     }
    43     while(ch>='0'&&ch<='9'){
    44         x=(x<<1)+(x<<3)+(ch^48);
    45         ch=getchar();
    46     }
    47     return x*f;
    48 }
    49 int main()
    50 {
    51     cin>>m>>n;
    52     for(int i=1;i<=n;i++)
    53     {
    54         for(int j=1;j<=m;j++)
    55         {
    56             mp[i][j]=read(); 
    57             if(mp[i][j]==2)//记录贝茜 
    58             {
    59                 sx=i;
    60                 sy=j;
    61             }
    62             if(mp[i][j]==3)//记录骑士 
    63             {
    64                 ex=i;
    65                 ey=j;
    66             }
    67             bu[i][j][0]=999999;//初始化 
    68             bu[i][j][1]=999999;
    69         }
    70     }
    71     bfs(sx,sy,0);//以贝茜为起点开始搜索 
    72     for(int i=1;i<=n;i++)
    73     {
    74         for(int j=1;j<=m;j++)
    75         {
    76             flag[i][j]=0;//初始化 
    77         }
    78     }
    79     bfs(ex,ey,1);//以骑士为起点开始搜索 
    80     for(int i=1;i<=n;i++)
    81     {
    82         for(int j=1;j<=m;j++)
    83         {
    84             if(mp[i][j]==4)//是树丛就相加取最优 
    85             {
    86                 ans=min(ans,bu[i][j][0]+bu[i][j][1]);
    87             }
    88         }
    89     }
    90     cout<<ans;
    91 }

    解题思路2

      先从贝茜开始搜索,搜到树丛时开始向骑士搜,等于树丛是一个中转站,没有打标记操作,都用步数作比较判断是否搜索过。

    题解2

      

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m;
     4 int mp[1001][1001];//存图 
     5 int vis[1001][1001][2];//记录步数 
     6 int dir[4][2]={0,1,0,-1,1,0,-1,0};//方向 
     7 struct node{
     8     int x;
     9     int y;//坐标 
    10     int t;//步数 
    11     bool f;//0为贝茜向树丛搜,1为树丛向骑士搜 
    12 };
    13 queue<node> q;
    14 int ans=0x3f3f3f3f;//初始化 
    15 inline int read(){//快读,不加过不了 
    16     int x=0,f=1;
    17     char ch=getchar();
    18     while(ch<'0'||ch>'9'){
    19         if(ch=='-')
    20             f=-1;
    21         ch=getchar();
    22     }
    23     while(ch>='0'&&ch<='9'){
    24         x=(x<<1)+(x<<3)+(ch^48);
    25         ch=getchar();
    26     }
    27     return x*f;
    28 }
    29 int main()
    30 {
    31     cin>>m>>n;
    32     for(int i=1;i<=n;i++)
    33     {
    34         for(int j=1;j<=m;j++)
    35         {
    36             mp[i][j]=read();
    37             if(mp[i][j]==2)//记录起点 
    38             {
    39                 q.push((node){i,j,0,0});
    40             }
    41         }
    42     }
    43     memset(vis,0x3f3f3f3f,sizeof(vis));//初始化步数 
    44     while(!q.empty())
    45     {
    46         node head=q.front();
    47         q.pop();
    48         if(mp[head.x][head.y]==3)//搜到终点 
    49         {
    50             ans=min(ans,head.t);//取最小值 
    51         }
    52         for(int i=0;i<4;i++)
    53         {
    54             int tx=head.x+dir[i][0];
    55             int ty=head.y+dir[i][1];
    56             if(tx<1||tx>n||ty<1||ty>m||mp[tx][ty]==1)continue;//越界或者障碍物 
    57             if(mp[tx][ty]==3&&!head.f)continue;//贝茜不能搜到骑士 
    58             bool flag=head.f;
    59             if(mp[tx][ty]==4)flag=true;//搜到树丛改变标记 
    60             if(vis[tx][ty][flag]<=head.t+1)continue;//更优 
    61             vis[tx][ty][flag]=head.t+1;
    62             q.push((node){tx,ty,head.t+1,flag});//进队列 
    63         }
    64     }
    65     cout<<ans;//输出步数 
    66     return 0;
    67 }
    68     
  • 相关阅读:
    把枚举类型绑定到datasource
    关于linq使用建议
    VS2012恢复默认设置的2种方法
    Manifold learning-based methods for analyzing single-cell RNA-sequencing data
    Single cell RNA-seq denoising using a deep count autoencoder
    scImpute——An accurate and robust imputation method scImpute for single-cell RNA-seq data
    第三代测序popular workflow
    js作用域闭包
    select的option选项左右移动
    添加区域练级联动
  • 原文地址:https://www.cnblogs.com/hualian/p/11199522.html
Copyright © 2011-2022 走看看