您的位置:首页 > 其它

六数码 广搜例题 附带一些实用的小用法

2017-11-16 11:42 204 查看

六数码这道题本身是一道广搜的例题 主要部分是广搜模版 大多数人已重复多遍 应该已经掌握 所以我在此说一下小细节 反正模版我是会的 小细节我真的不会

看大佬的博客学会了这些细节 在这里把精华详细地说出来 b数在心 大佬勿笑 如有不对 还望指正

但是这些小细节只能一点一点积累了

1.队列的清空 操作如下

while(!q1.empty())

{

 q1.pop(); // 队首元素一直出队直到队列为空达到清空队列的作用

}

2.used的清空  used数组是定义在map这个头文件上面的

used.clear

3.具体怎么输出的问题

我发现这个题目提交的时候有个bug 我用了本来写好的程序提交是对的 然后改了一点提交也是对的 这就比较纠结了  我又看了一遍题目 发现我犯了一个比较扯淡的错误

我觉得这个问题应该不只我一个人犯吧 只有我当时脑子短路我也是比较无奈的

输出方法1 : 输入一个测例 输出一个测例的结果 如此运行下去 这么提交是对的 但是不符合题意  题意应该是一口气输出多个测例的结果 这个问题应该比较常见 应避免

效果大概是这样的 (在这里我只列举两个测例):

第一步 : 输入 1 3 2 4 5 6

第二步 : 回车 这时候就输出 No 了 (明显不符合题意)

第三步 :再输入 1 3 2 4 5 6

第四步 : 回车 这时候还输出 No

第五步 : 按ctrl+z

第六步 : 回车 程序结束

输出方法2 : 在我思考人生之后觉得这么理解应该是比较正确的 用一个数组存一下每个测例得出的结果 最后再一口气输出全部测例的结果

改正后的效果

第一步 : 输入 1 3 2 4 5 6

第二步 : 回车 这时候不会输出

第三步 :再输入 1 3 2 4 5 6

第四步 : 回车 这时候还不会输出

第五步 : 按ctrl+z

第六步 : 回车 输出结果程序结束 (这时候我就觉得效果比较符合题意了 如果我的理解有问题 还望指正 共同进步)

题目和代码如下

现有一两行三列的表格如下:

A B C

D E F

把1、2、3、4、5、6六个数字分别填入A、B、C、D、E、F格子中,每个格子一个数字且各不相同。每种不同的填法称为一种布局。如下:

1 3 5

2 4 6

布局1

2 5 6

4 3 1

布局2

定义α变换如下:把A格中的数字放入B格,把B格中的数字放入E格,把E格中的数字放入D格,把D格中的数字放入A格。

定义β变换如下:把B格中的数字放入C格,把C格中的数字放入F格,把F格中的数字放入E格,把E格中的数字放入B格。

问:对于给定的布局,可否通过有限次的α变换和β变换变成下面的目标布局:

1 2 3

4 5 6

目标布局

输入:

本题有多个测例,每行一个,以EOF为输入结束标志。每个测例的输入是1到6这六个数字的一个排列,空格隔开,表示初始布局ABCDEF格中依次填入的数字。

输出:

每个输出占一行。可以转换的,打印Yes;不可以转换的,打印No。

输入样例:

1 3 5 2 4 6
2 5 6 4 3 1

输出样例:

No
Yes

#include<iostream>

 #include<stdio.h>

 #include<math.h>

 #include<queue>//队列解决广搜问题

#include<map>//使用map是为了方便标记

 #include<stdlib.h>

 using namespace std ;

 queue<int>q1 ;

 map<int , int> used ;//判断是否遍历过

int bfs() ; //广搜找答案

int moveto(int u , int dire) ;

 void print(int n) ;

  //1 3 5 2 4 6

 //2 5 6 4 3 1

 int main()

 {

     int num = 0 , i , m , n  , a[100] , counter = 0 ;

     while(scanf("%d",&m)!=EOF)//以EOF为结束标志 

    {  

         num = m ;

        

         for(i = 0 ; i < 5 ; i++)

         {

             scanf("%d" , &m);

             num = num * 10 + m ;

         }//将输入的布局直接转为6位数

      while(!q1.empty()) // 队首一直出队直到队列为空             

        {

            q1.pop();

        }

        used.clear();//多组数据 需要清空used 

       

       

         q1.push(num);//将起点加入队列

         used[num]=1;

         a[counter] = bfs() ;//输出搜索的结果

         counter ++ ;

        }

       for(i = 0 ; i < counter ; i++)

       {

   

         if(a[i]==0) printf("No\n");//输出结果

         if(a[i]==1) printf("Yes\n");

      

    }

  return 0;

 }

int bfs()//广搜找答案 这个子函数是广搜的模版 已练习多遍

 {

  int i , u , v ;

  while(!q1.empty())

  {

   u = q1.front() ;

   q1.pop() ;

   for(i = 1 ; i <= 2 ; i++)

   {

    v = moveto (u , i) ;

    if(v == 123456)

    {

     return 1 ;//找的到解 return 1 

    }

    if(used.count(v) == 0)

    {

     q1.push(v) ;

     used[v] = 1 ;

    }

   }

  }

  return 0 ;//找不到解 return 0

 }

 int moveto(int u , int dire)

 {

 /*定义α 把A b[0][0] B b[0][1],把B b[0][1]  E b[1][1],把E b[1][1] D b[1][0],把D b[1][0]  A b[0][0]。

 定义β   把B b[0][1] C b[0][2],把C b[0][2]  F b[1][2],把F b[1][2] E b[1][1],把E b[1][1] B b[0][1]

 */

  int i , j , b[2][3] , v = 0 , temp1 , temp2 , temp3 , temp4 ;

  if(dire == 1) // a转换

  {

    for(i = 1 ; i >= 0 ; i--)

    {

     for(j = 2 ; j >= 0 ; j--)

     {

       b[i][j] = u % 10 ;

     u /= 10 ;

     }

    }

       temp1 = b[0][0] ;//设置多个临时变量方便转换

       temp2 = b[0][1] ;

       temp3 = b[1][1] ;

       temp4 = b[1][0] ;

       b[0][1] = temp1 ;

       b[1][1] = temp2 ;

       b[1][0] = temp3 ;

       b[0][0] = temp4 ;

      

    for(i = 0 ; i <= 1 ; i++)

    {

     for(j = 0 ; j <= 2 ; j++)

     {

      v = v * 10 + b[i][j] ;

     }

    }

    return v ;

  }

  //把B b[0][1] C b[0][2],把C b[0][2]  F b[1][2],把F b
4000
[1][2] E b[1][1],把E b[1][1] B b[0][1]

  else  // b转换 方法和a相同

  {

      for(i = 1 ; i >= 0 ; i--)

      {

       for(j = 2 ; j >= 0 ; j--)

       {

        b[i][j] = u % 10 ;

        u /= 10 ;

       }

      }

         temp1 = b[0][1] ;

         temp2 = b[0][2] ;

         temp3 = b[1][2] ;

         temp4 = b[1][1] ;

         b[0][2] = temp1 ;

         b[1][2] = temp2 ;

         b[1][1] = temp3 ;

         b[0][1] = temp4 ;

   for(i = 0 ; i <= 1 ; i++)

    {

      for(j = 0 ; j <= 2 ; j++)

      {

      v = v * 10 + b[i][j] ;

      }

    }

      return v ;

  }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: