zoukankan      html  css  js  c++  java
  • poj1915 广度优先遍历

    poj1915 广度优先遍历

    问题重述: 背景 神话般的国际象棋玩家Somurolov先生,他声称,他可以把一个骑士从一个位置很快地移动到另一个位置,但其他人却不行。你能打败他吗? 存在的问题 你的任务是编写一个程序来计算的骑士达到从另一个位置所要移动的最少步数,这样你才有机会比Somurolov快。 也许人们不熟悉的国际象棋,骑士行动可能在如图1所示。 输入 首先在第一个行,输入n,表示有n种的情况。 接下来是n方案。每个方案包括三行。第一行指定一个棋盘边长L(4<=L<= 300)。整个棋盘的尺寸L *L.第二和第三行包含整数对(0,...,L - 1)*(0,...,L - 1)指定骑士开始和结束位置。整数对由一个空白分隔开。 输出 对于每个输入你要计算骑士的行动,有必要从起点移动到终点最少步数的情况。如果起点和终点都是平等的,距离是零。 2.解题过程: 分析过程: 当读懂了题意后,发现这可能是一道最短路径的应用,但当看到图算法的题目后,再仔细想下,这是一道广度优先遍历的应用,利用广搜去求最短路径比较简单。采用广度优先去搜索,一旦找到了就可以由搜索的深度去求出所需的最少步数。而广度优先的算法要用到队列,平时也做过练习,所以在算法上也就没有什么问题。而这道题的数据的输入问题,相对挺简单的。但存储就有点麻烦,因为棋盘的大小是从4*4到300*300,跨度比较大,如果只是定义最大的二维数组来存储,可能会浪费很多空间,此外,队列要存储的是一个棋盘的格子,所以要存至少两个数,为了方便,我直接使用两个整型的队列存储两个下标,感觉不难。 编程过程: 到了具体编程时,我才发现,如何由搜索的深度去求出所需的最少步数,这一步的实现挺麻烦的。我之前打算直接用以前写过的int型队列难以实现,除了要记录棋格的x,y坐标,还要记录棋格的步数。要不就只能重新定义一个新的结构体的队列,要不就得多个队列并行使用,但两者都挺麻烦的。所以我就想到如果我C++里有直接的队列可以使用,但我不会C++。最后发现poj上是可以提交java代码的,再想到下学期我得考sun的scjp认证,得复习下java。所以,最后打算用java来做。于是,我很快就用java把代码编出来了,自己测试也通过了,但提交时却说内存溢出。想了很久后,就大概猜到是什么原因,最初我是在得到size后就把整张棋盘都建了出来。这样就产生了很多的对象,自然多了许多没有用的对象霸占了许多内存。之后我就改为当需要时才去建棋格子的对象,果然少占了很多内存。但提交时,却发现运行错误,可是我自己测试却没问题,所以郁闷了很久。最后,发现有的地方会出现空指针异常,终于通过了。

     1 #include<queue>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cstdio>
     6 using namespace std;
     7 int map[305][305],sx,sy,ex,ey,n,dist[305][305];
     8 int a[8][2]= {1,2,1,-2,-1,2,-1,-2,2,1,2,-1,-2,1,-2,-1};
     9 //1,1,-1,-1,2,2,-2,-2};
    10 //2,-2,2,-2,1,-1,1,-1};
    11 struct point
    12 {
    13     int xx,yy;
    14 };
    15 point pp,p;
    16 int x,y;
    17 
    18 int bfs()
    19 {
    20     queue <point>q;//此处存疑,为什么这一句放在函数体外面就不对?
    21     memset(map,0,sizeof(map));
    22     memset(dist,0,sizeof(dist));
    23     pp.xx=sx;
    24     pp.yy=sy;
    25     map[sx][sy]=1;
    26     q.push(pp);
    27     int tx,ty;
    28     while(!q.empty())
    29     {
    30         pp=q.front();
    31         x=pp.xx;
    32         y=pp.yy;//x和y存储的是tx和ty的前一个点
    33         q.pop();
    34         if(x==ex&&y==ey)break;
    35 
    36 
    37         for(int i=0; i<8; i++)
    38         {
    39             tx=x+a[i][0];
    40             ty=y+a[i][1];
    41             if(tx>=0&&ty>=0&&tx<n&&ty<n&&map[tx][ty]==0)
    42             {
    43                 dist[tx][ty]=dist[x][y]+1;
    44                 p.xx=tx;
    45                 p.yy=ty;
    46                 q.push(p);
    47                 map[tx][ty]=1;
    48             }
    49         }
    50     }
    51 
    52 
    53 }
    54 int main()
    55 {
    56     int t;
    57     scanf("%d",&t);
    58     while(t--)
    59     {
    60         scanf("%d",&n);
    61         scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
    62         bfs();
    63         printf("%d
    ",dist[ex][ey]);
    64     }
    65     return 0;
    66 }
  • 相关阅读:
    面向对象第6课——多态——接口
    面向对象第6课——多态——抽象
    面向对象第5课——转型
    面向对象第5课——继承
    bank
    0923异常——练习题目作业
    0923接口——练习题作业
    0922继承,练习题目-作业
    RecyclerView三列展示及单列展示
    bitmap转换为drawable
  • 原文地址:https://www.cnblogs.com/SSYYGAM/p/4509684.html
Copyright © 2011-2022 走看看