POJ1321,深度优先搜索

来源:互联网 发布:第十一届网络作家榜单 编辑:程序博客网 时间:2024/06/04 19:41

这道题目呢,思路是比较清晰的,首先肯定得用深搜,用两个标记数组,一个用来标记某一行是否已走,另一个用来标记某一列是否已走,然后在满足条件的情况下,搜出最多的可行方案。然而呢,我这个菜狗,竟然没把代码写好,改了好半天,还是WA,好弱啊。。。

(这段话,大家可以不用看了= =,刚开始的代码bug出现在哪呢,

4 4...#..#..#..#...
把满足条件的(0,3),(1,2),(2,1),(3,0)跑完了之后呢,看最后一行还有没有其他的点满足条件的,确认没有之后呢,回溯到倒数第二行,在这之前呢,把(3,0)这个点呢,恢复到可走状态,然后在倒数第二行,没发现除(2,1)之后的其他点,因为我在每一个dfs里面呢,都是两层for循环,所以就跑到了下一行,最后又得到了一组“正确的”结果(0,3),(1,2),(3,0),(2,1)

后来呢,我又开了一个标记数组,用来标记某个点是否已经走过,这样的话,就不会出现上面的情况了,因为(3,0)这个点已经走过了,所以不会再走了。。。。但是呢,又出现了一个问题,就是如果在倒数第二行除了(2,1)点之外呢,还有满足条件的点,那么由于换了点,所以最后一层的点应该要重新和这个点结合一起看是否满足题目条件,但是呢由于最开始最后一层的点已经走过,被标记为不可走了,所以呢,这种情况下,也不会走。。。。。想了半天,不得其解,我好弱啊= =

#include<cstdio>#include<iostream>#include<cstring>#include<queue>using namespace std;const int maxn = 10;char ch[maxn][maxn];//存棋盘int vis[maxn];//vis[i],用来标记第i列是否可走int n,m;//n行n列,m个棋子int cnt,num;//cnt是最后可行的方案数,num是当前已经有几个棋子下好了void dfs(int i)//i表示第i行{    if (num == m)    {        ++cnt;//如果当前已经有m个棋子下好了,说明这种方案可行        return ;    }    if (i >= n)//n行的图,超过了n-1,就不在图范围内了        return ;    for (int j = 0; j < n; ++j)//遍历某一行的所有列    {        if (!vis[j] && ch[i][j] == '#')        {            vis[j] = 1;            ++num;            dfs(i+1);            vis[j] = 0;//回溯的时候,这列重新可走            --num;//回溯        }    }    dfs(i+1);//对于这一条语句的作用,可以这样理解,如果有一行(不是最后一行),    //字符全部都是.,没有#,如果没有这一条语句,那么由于没有#,所以在跑上面的for    //循环时,不会递归到下一行,跑完了for循环就回溯到上一行了,但事实上呢,这一行    //的下面还有图,但是都不会再跑,所以这就是这一条语句的作用}int main(){    int i,j;    while (~scanf("%d%d",&n,&m))    {        if (n == -1 && m == -1)            break;        for (i = 0; i < n; ++i)//输入棋盘        {            getchar();            for (j = 0; j < n; ++j)                scanf("%c",&ch[i][j]);        }        memset(vis,0,sizeof(vis));//刚开始每一列都可下棋子        cnt = 0;        num = 0;        dfs(0);        printf("%d\n",cnt);    }    return 0;}/*这段代码是怎么解决我之前的那两个bug的呢?首先这里的dfs搜的是特定的某一行,并且不回溯的话,行是不会减小的,也就是说,对于(0,3),(1,2),(3,0),(2,1)这段bug结果,如果找到了(3,0)点,是不会再找到(2,1)这个点的(仔细体会上面的代码过程!)第二个bug的解决是回溯的时候,列重新标记为可走状态!感觉这段代码最重要之处,就是它的每一次dfs只是遍历特定的某一行*/


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 在香港海关被扣怎么办 发现被医院骗了怎么办 白皮子科染上血怎么办 宝宝头发里长湿疹怎么办 婴儿头发里长湿疹怎么办 宝宝解小便地方有湿疹怎么办 婴儿湿疹怎么办长在脸上 广州奥龙堡游泳卡过期了怎么办 大学生在学校当兵户口怎么办 茶叶梗枕头太硬怎么办 茶梗枕头太硬怎么办 照片放久了变红怎么办 乳腺萎缩和韧带松弛怎么办 航海王启航服务器爆满怎么办 LOL记分板没了怎么办 辅导孩子做作业没有耐心怎么办 宝宝住院三天回家不吃母乳怎么办 锁频君把应用变暗了怎么办 95的油加成92的怎么办 倒库一边宽了怎么办 倒库老是倒不好怎么办 倒库方向打早了怎么办 倒库左边小了怎么办 倒车入库小于30公分怎么办 倒库大于30公分怎么办 有行车记录仪遇到碰瓷怎么办 狗换了主人不吃怎么办 遇到扔东西碰瓷怎么办 碰见碰瓷的人怎么办 开店遇上碰瓷的顾客怎么办 我刮到别人的车怎么办 新车被刮了漆怎么办 停车擦到别人车怎么办 骑自行车被汽车撞了怎么办 车停在小区被刮怎么办 机动车被自行车撞了怎么办 单车撞小车后被起诉怎么办 给小车撞到电动单车怎么办 车停在路边被自行车撞怎么办 撞了碰瓷的人怎么办 谷丙转氨酶46该怎么办