野人过河问题

这是某安全公司的笔试题,它的题目包括几十道选择题,和一道主观题,即野人过河问题。选择题涉及智力题、计算机组成原理、正则、C语言、操作系统等方面,而主观题,则是搜索中的经典题型。

野人过河问题题意如下:

有M个牧师(也有的翻译为传教士)和C个野人过河,只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于牧师的人数,那么牧师就会有危险. 你能不能找出一种安全的渡河方法呢(M>=C)?

可惜,在紧张的笔试过程中,我虽然想到了可能是搜索,但是,算法的不熟练导致我并不能够非常快速的将搜索算法写出来。估计笔试跪了,写出来,供后人参考吧。

其实就是五种状态:

1.两个野人过河

2.两个牧师过河

3.一个野人一个牧师过河

4.一个牧师过河

5.一个野人过河

只需对这5种状态进行搜索,直到得到问题的解,或者得到问题无解,搜索过程即终止。

代码如下:

#include<iostream>
#include<string>
#include<vector> 
using namespace std;
vector<string> vect;
bool boat = true;//true表示船在对岸 
//用深度搜索的方法进行解答
bool dfs(int m,int c,int M,int C){

     char s[30]; 
     //非法状态
     if(m<0||c<0||M<0||C<0){
                            
          return false;                       
     }     
     
     //野人多于传教士,传教士会被吃掉
     if((m&&c>m)||(M&&C>M)){
                            
          return false;                       
     } 
     
     //运送到了对岸
     if((boat&&M==0&&C==0)||(!boat&&m==0&&c==0)){
     
          return true;                                            
     } 
     
     if(boat==true){
     
           sprintf(s,"M=%d,C=%d,m=%d,c=%d,boat=right",M,C,m,c);            
     }else{
     
           sprintf(s,"M=%d,C=%d,m=%d,c=%d,boat=left",M,C,m,c);      
     } 
     
     for(int i=0;i<vect.size();i++){
     
             //如果此状态已存在过 
             if(vect[i]==s){
             
                            return false;               
             }        
     } 
     
     //搜索五种状态
     boat = !boat;
     vect.push_back(s); 
     if(dfs(m+2,c,M-2,C)){
                          
            cout<<"两个传教士过河."<<endl;
            return true; 
     }else if(dfs(m,c+2,M,C-2)){
           
            cout<<"两个野人过河."<<endl;
            return true;    
     }else if(dfs(m+1,c+1,M-1,C-1)){
           
            cout<<"一个野人和一个传教士过河."<<endl;
            return true;    
     }else if(dfs(m+1,c,M-1,C)){
           
            cout<<"一个传教士过河."<<endl;
            return true;      
     }else if(dfs(m,c+1,M,c-1)){
           
            cout<<"一个野人过河."<<endl;
            return true;      
     } 
     boat = !boat;
     vect.pop_back();
    
     return false; 
} 
int main() {
    
    //假设一种情况
    int M=6,C=6,m=0,c=0;
    char s[30]; 
    sprintf(s,"M=%d,C=%d,m=%d,c=%d,boat=left",M,C,m,c); 
    cout<<s<<endl; 
    if(!dfs(m,c,M,C)){
    
                      cout<<"can not find a solution."<<endl;                  
    } 
    
    system("pause");
    return 0;    
} 


我是搞JAVA的,搞JAVA的非常苦逼。因为在笔试上爹不疼娘不爱的,大部分笔试是考C/C++基础,对于专注于JAVA的童鞋来说,必须要对C/C++进行复习,很痛苦的。建议能够搞C/C++还是搞C/C++吧!至少在笔试面试上是非常占优的。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值