zoukankan      html  css  js  c++  java
  • BFS解决八数码问题和狼人过河问题

    1、八数码问题

    问题描述:

    初态:

    0    1    2

    3    4    5

    6    7    8

    如何移动交换0的位置达到终态

    1    2     3

    4    5     6

    7    8     0

    思路如下:

    先将图转换为一个整数

    初态:
    876543210
    终态:
    087654321

    构造状态的数据结构

    struct node{
    int x;
    int where0;
    }

    运动规则如下

    switch where0:
    case0: d,r
    case1: d,l,r
    case2: d,l
    case3: u,d,r
    case4: u,d,l,r
    case5: u,d,l
    case6: u,r
    case7: u,l,r
    case8: u,l

    switch dir:
    case u:t=x/10^(where0-3)%10; x=x-10^(where0-3)*t+10^where0*t;
    case d:t=x/10^(where0+3)%10; x=x-10^(where0+3)*t+10^where0*t;
    case l:t=x/10^(where0-1)%10; x=x-10^(where0-1)*t+10^where0*t;
    case r:t=x/10^(where0+1)%10; x=x-10^(where0+1)*t+10^where0*t;

    代码:

      1 #include<iostream>
      2 #include<map>
      3 #include<queue>
      4 #include<cstdlib> 
      5 using namespace std;
      6 
      7 int pow10[10]={1,10,100,1000,10000,100000,
      8 1000000,10000000,100000000,1000000000};
      9 
     10 //数据结构 
     11 struct node{
     12     int x;//表示当前状态图 
     13     int where0;//0的位置 
     14     struct node *pre;//父节点 
     15 };
     16 
     17 //运动规则 
     18 node * goAction(node *p,int dir){
     19     int x=p->x,where0=p->where0;
     20     node *ans=(node *)malloc(sizeof(node));
     21     ans->pre=p;
     22     int t;
     23     switch(dir){
     24         case 1://up
     25             t=x/pow10[where0-3]%10;
     26             x=x-pow10[where0-3]*t+pow10[where0]*t;
     27             where0-=3;
     28             break;
     29         case 2://down
     30             t=x/pow10[where0+3]%10;   
     31             x=x-pow10[where0+3]*t+pow10[where0]*t;
     32             where0+=3;
     33             break;
     34         case 3://left
     35             t=x/pow10[where0-1]%10;   
     36             x=x-pow10[where0-1]*t+pow10[where0]*t;
     37             where0-=1;
     38             break;
     39         case 4://right
     40             t=x/pow10[where0+1]%10;   
     41             x=x-pow10[where0+1]*t+pow10[where0]*t;
     42             where0+=1;
     43             break;
     44     }
     45     ans->x=x;
     46     ans->where0=where0;
     47     return ans;    
     48 }
     49 
     50 queue<node *>nq;//状态队列 
     51 map<int,int>nm;//判重 
     52 
     53 //新节点加入队列 
     54 int join(node *a){
     55     if(nm[a->x]==1)//重复节点不加入队列 
     56         return 0;
     57     if(a->x==87654321){//抵达终态 
     58         cout<<"路径:"<<endl; 
     59         node *h=a;
     60         int step=0;
     61         while(h!=NULL)//打印路径和步数 
     62         {
     63             cout<<h->x<<"  ";
     64             step++;
     65             h=h->pre;        
     66         }
     67         cout<<step<<endl;
     68         return 1;
     69     }
     70     nm[a->x]=1;
     71     nq.push(a);//加入队列 
     72     return 0;
     73 }
     74 
     75 void fun(){
     76     
     77     while(!nq.empty()){
     78         node *p=nq.front();
     79         nq.pop();
     80         switch(p->where0){//运动规则 
     81             case 0:
     82                 join(goAction(p,2));
     83                 join(goAction(p,4));
     84                 break;
     85             case 1:
     86                 join(goAction(p,2));
     87                 join(goAction(p,3));    
     88                 join(goAction(p,4));
     89                 break;
     90             case 2:
     91                 join(goAction(p,2));
     92                 join(goAction(p,3));
     93                 break;
     94             case 3:
     95                 join(goAction(p,1));
     96                 join(goAction(p,2));
     97                 join(goAction(p,4));
     98                 break;
     99             case 4:
    100                 join(goAction(p,1));
    101                 join(goAction(p,2));
    102                 join(goAction(p,3));
    103                 join(goAction(p,4));
    104                 break;
    105             case 5:
    106                 join(goAction(p,1));
    107                 join(goAction(p,2));
    108                 join(goAction(p,3));
    109                 break;
    110             case 6:
    111                 join(goAction(p,1));
    112                 join(goAction(p,4));
    113                 break;
    114             case 7:
    115                 join(goAction(p,1));
    116                 join(goAction(p,3));
    117                 join(goAction(p,4));
    118                 break;
    119             case 8:
    120                 join(goAction(p,1));
    121                 join(goAction(p,3));
    122                 break;
    123 
    124         }
    125             
    126     }
    127      
    128 }
    129 
    130 int main()
    131 {
    132     node *begin=(node *)malloc(sizeof(node));//初始状态 
    133     begin->x=876543210;
    134     begin->where0=0;
    135     begin->pre=NULL;
    136     join(begin);
    137     fun();
    138 
    139 
    140 }

    2、狼人过河问题

    问题描述:

    {wolf,human,boat}
    分别代表右岸的狼,人,船的数目

    初态:{3,3,1}
    终态:{0,0,0}

    如何从初态抵达终态

    规则:
    1、每次过河船上可以一人或两人
    switch boat:
    case 0:
    boat++;
    wolf+=1||wolf+=2||human+=1||human+=2||wolf+=1,human+=1;
    case 1:
    boat--;
    wolf-=1||wolf-=2||human-=1||human-=2||wolf-=1,human-=1;
    2、两岸的狼不能比人多(人数不为0时)
    no1:wolf<0||wolf>3||human<0||human>3||boat<0||boat>1
    no2:(human>0&&human<wolf)||((3-human)>0&&(3-human)<(3-wolf))

    数据结构

    struct node{
    int wolf;
    int human;
    int boat;
    struct node *pre;
    };

    代码:

      1 #include<iostream>
      2 #include<map>
      3 #include<queue>
      4 #include<cstdlib> 
      5 #include<String>
      6 using namespace std;
      7 
      8 struct node{
      9 int wolf;
     10 int human;
     11 int boat;
     12 struct node *pre;
     13 void init(int a,int b,int c,struct node *p){
     14     this->wolf=a;
     15     this->human=b;
     16     this->boat=c;
     17     this->pre=p;
     18 }
     19 
     20 bool operator < (const node x) const{//重载运算符,注意map是基于红黑树实现,每个节点需要具备可比性 
     21     int hash1=this->wolf*100+this->human*10+this->boat;
     22     int hash2=x.wolf*100+x.human*10+x.boat;
     23     return hash1<hash2;
     24 }
     25 
     26 
     27 
     28 };
     29 
     30 queue<node *>nq;//状态队列 
     31 map<node,int>nm;//状态判重 
     32 
     33 //判断能否加入队列 
     34 int join(node *a){
     35     if(nm[*a]==1)
     36         return 0;
     37     int wolf=a->wolf,human=a->human,boat=a->boat;
     38     if(wolf<0||wolf>3||human<0||human>3||boat<0||boat>1)
     39         return 0;
     40     if((human>0&&human<wolf)||((3-human)>0&&(3-human)<(3-wolf)))
     41         return 0;
     42     if(a->wolf==0&&a->human==0&&a->boat==0){//终态 
     43         node *h=a;
     44         int step=0;
     45         while(h!=NULL){//打印路径和步数 
     46             step++;
     47             cout<<"{ "<<h->wolf<<" , "<<h->human<<" , "<<h->boat<<" }  ";
     48             h=h->pre;
     49         }
     50         cout<<endl;
     51         cout<<step<<endl;
     52         return 1;
     53     }
     54     nm[*a]=1;
     55     nq.push(a);
     56     return 0;
     57 }
     58 
     59 //运动规则 
     60 void goAction(node *p){
     61     node *a=(node *)malloc(sizeof(node));
     62     node *b=(node *)malloc(sizeof(node));
     63     node *c=(node *)malloc(sizeof(node));
     64     node *d=(node *)malloc(sizeof(node));
     65     node *e=(node *)malloc(sizeof(node));
     66     switch(p->boat){
     67         case 0://注意,不能在case里新建变量 
     68             
     69             a->init(p->wolf+1,p->human,1,p);
     70             join(a);
     71             
     72             b->init(p->wolf+2,p->human,1,p);
     73             join(b);
     74             
     75             c->init(p->wolf,p->human+1,1,p);
     76             join(c);
     77             
     78             d->init(p->wolf,p->human+2,1,p);
     79             join(d);
     80             
     81             e->init(p->wolf+1,p->human+1,1,p);
     82             join(e);
     83             break;
     84         case 1:
     85             
     86             a->init(p->wolf-1,p->human,0,p);
     87             join(a);
     88             
     89             b->init(p->wolf-2,p->human,0,p);
     90             join(b);
     91             
     92             c->init(p->wolf,p->human-1,0,p);
     93             join(c);
     94             
     95             d->init(p->wolf,p->human-2,0,p);
     96             join(d);
     97             
     98             e->init(p->wolf-1,p->human+1,0,p);
     99             join(e);
    100             break;
    101     }
    102     return;
    103 }
    104 
    105 
    106 
    107 void fun(){
    108     while(!nq.empty()){
    109         node *p=nq.front();
    110         nq.pop();
    111         goAction(p);
    112     }
    113     
    114 }
    115 
    116 int main(){
    117     node *begin=(node *)malloc(sizeof(node));//初态 
    118     begin->init(3,3,1,NULL);
    119     join(begin);
    120     fun();
    121 
    122 }
  • 相关阅读:
    codevs1842 递归第一次
    codevs1501 二叉树最大宽度和高度
    (noi.openjudge.cn) 1.5编程基础之循环控制T36——T45
    (noi.openjudge.cn) 1.7编程基础之字符串T21——T30
    (noi.openjudge.cn) 1.9编程基础之顺序查找T06——T15
    (noi.openjudge.cn) 1.9编程基础之顺序查找T01——T05
    (noi.openjudge.cn) 1.7编程基础之字符串T31——T35
    (noi.openjudge.cn) 1.8编程基础之多维数组T21——T25
    Objective-C/C++混编编译器设置
    UITableView使用指南
  • 原文地址:https://www.cnblogs.com/eastblue/p/9821237.html
Copyright © 2011-2022 走看看