BFS寻找路径并记录,及二分应用(学习笔记)

广度优先搜索

对比深搜来说,广搜在某种特定情况下要比深搜快得多,例如找迷宫最短路径,此时用广搜就要优于深搜。这不是有没有使用递归的问题,而是在算法层面的快。
例如:
定义一个二维数组:
int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

这是一道很基础的搜索题,用深搜也可以,但是如果选择用深搜来写,而意味着你需要把所有的情况全部都走一遍,比较他们的大小再选择。而且这样写并不好保存路径,你要做的变成了两步:1,找到最短路径2,更新至最短路径的路径值,很麻烦。
但如果选择广搜的话就不一样了,广搜优先的是所有路,也就是说,当你走到目标点时,此时结束就是最短的路径。并且和深搜不一样的是,广搜的每一中路径都保存在队列里,这方便了我们打印路径

#include 
#include 
struct note
{
    int x;
    int y;
    int s;
    int f;
};
int main()
{
    struct note que[50];
    int a[51][51]={0},book[51][51]={0},shu[50][2],w;
    int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
    int head,tail;
    int i,j,k,n,m,startx,starty,p,q,tx,ty,flag;

    for(i=1;i<=5;i++)
        for(j=1;j<=5;j++)
        scanf("%d",&a[i][j]);

    head=1;
    tail=1;
    que[tail].x=1;
    que[tail].y=1;
    que[tail].f=0;
    que[tail].s=0;
    tail++;
    book[1][1]=1;
    flag=0;
    while(head<tail)
    {
        for(k=0;k<=3;k++)
        {
            tx=que[head].x+next[k][0];
            ty=que[head].y+next[k][1];
            if(tx<1||tx>5||ty<1||ty>5)
                continue;
            if(a[tx][ty]==0&&book[tx][ty]==0)
            {
                book[tx][ty]=1;
                que[tail].x=tx;
                que[tail].y=ty;
                que[tail].f=head; //这里就是用来记录路径的
                que[tail].s=que[head].s+1;
                tail++;
            }
            if(tx==5&&ty==5)
            {
                flag=1;
                break;
            }
        }
        if(flag==1)
            break;
        head++;
    }
    tail=tail-1;
    shu[0][0]=5;
    shu[0][1]=5;
    w=1;
    while(que[tail].f!=0)
    {
        shu[w][0]=que[que[tail].f].x;    //用刚才保存的东西来逆向探寻出路
        shu[w][1]=que[que[tail].f].y;
        que[tail].f=que[que[tail].f].f;
        w++;
    }
    for(i=w-1;i>=0;i--)
    {
        printf("(%d, %d)",shu[i][0]-1,shu[i][1]-1);
        printf("\n");
    }
    return 0;
}

二分

二分的主要思想:

BFS寻找路径并记录,及二分应用(学习笔记)_第1张图片

是一种简单但实用的方法,但在使用二分时要注意:什么是二分的终点,什么是二分的参数。简而言之就是要知道分的是谁。像下面这道题,我们分的不是他的x,而是所取得和y,所以我们需要再写一个函数来计算不同mid下的返回的和。

Now,given the equation 8x^4 + 7x^3 + 2x^2 + 3x + 6 == Y,can you find its solution between 0 and 100;
Now please try your lucky.
Input
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has a real number Y (fabs(Y) <= 1e10);
Output
For each test case, you should just output one real number(accurate up to 4 decimal places),which is the solution of the equation,or “No solution!”,if there is no solution for the equation between 0 and 100.
Sample Input
2
100
-4
Sample Output
1.6152
No solution!

#include
#include
#include
double pan(double x);
double pan(double x)
{
    return 8*pow(x,4)+7*pow(x,3)+2*pow(x,2)+3*x+6;
}
void suan(double y)
{
     double mid;
     double shou,y1;
     y1=y;
     shou=0;
     while(1)
     {
         mid=(shou+y1)/2;
         if(pan(mid)>y)         //类似于找零点,要找到零点其实就要找到一边大于零另一边小于零的情况
         {
             y1=mid;
         }
         else if(pan(mid)<y)
         {
             shou=mid;
         }
         if(pan(mid)-y<0.000001&&pan(mid)-y>0)//这一步要尤其注意
         {
             printf("%0.4lf\n",mid);
             break;
         }
     }

}
int main()
{
    int t;
    double y;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf",&y);
        if(y<pan(0)||y>pan(100))
        {
            printf("No solution!\n");
        }
        else
        {
            suan(y);
        }
    }
    return 0;
}

你可能感兴趣的:(BFS寻找路径并记录,及二分应用(学习笔记))