对比深搜来说,广搜在某种特定情况下要比深搜快得多,例如找迷宫最短路径,此时用广搜就要优于深搜。这不是有没有使用递归的问题,而是在算法层面的快。
例如:
定义一个二维数组:
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;
}
二分的主要思想:
是一种简单但实用的方法,但在使用二分时要注意:什么是二分的终点,什么是二分的参数。简而言之就是要知道分的是谁。像下面这道题,我们分的不是他的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;
}