广东北电长沙站的程序笔试题

我没去参加笔试,但据比木同学说,广电的笔试很基础,总共就四道题:1、josephus数小孩问题。2、二分查找法。3、用栈实现递归。4、有关通信、网络方面的汉译英、英译汉。

用栈实现递归,我以前专门写过一篇文章。读者可以去翻来看看。现在,我自己来解答前两个问题。

1、josephus问题的描述:编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。设计一个程序来求出出列顺序。

解这道题有两种方法,一种是递归法、一种是选代法。给出程序:

/ /
// 递归法求解joseph问题,
/ /
// m:第一次的报数次数
// pos:报数的起始位置
// A[][2]:一个二维数组,A[i][0]存放成员的编号,A[i][1]存放成员的密码
// n:成员个数
void   joseph_1( int  m,  int  pos,  int  A[][ 2 ],  int  n)
{
    
// base case
     if  (n  ==   1 )
    {
        cout 
<< " 最后一个离开的是 " << A[ 0 ][ 0 ] << " " << endl;
        
return ;
    }

    
// 根据m值,求出将要离队的成员在数姐中的位置
    
// 考因为是循环数数,故用求模法
     int   out   =  (pos  +  m  - 1 ) % n;

    
// 根据离队成员的密码,决定下一次偏移量
    m  =  A[ out ][ 1 ];
    
    
// 离队的成员编号
     int  num  =  A[ out ][ 0 ];

    
// 离队处理
    cout  << " 成员 " << num << " 号离队 " << endl;

    
// 离开后,该成员后面的所有成员向前移动一位
     for  ( int  i = out ; i < n - 1 ; i ++ )
    {
        A[i][
0 =  A[i + 1 ][ 0 ];
        A[i][
1 =  A[i + 1 ][ 1 ];
    }

    
// 对下一次进行处理
    joseph(m,  out ,A, n - 1 );

}
// //
// 迭代法求解joseph问题
// /
void  joseph_2( int  m,  int  pos,  int  A[][ 2 ],  int  n)
{
    
int   out ;
    
while  (n  > 1 )
    {
        
// 离队的位置
         out   =  (pos  +  m  - 1 ) % n;

        
// 下一次离队的偏移量
        m  =  A[ out ][ 1 ];

        
// 离队公告
        cout  << " 成员 " << A[ out ][ 0 ] << " 号离队 " << endl;

        
// 紧凑队伍
         for  ( int  i = out ; i < n - 1 ; i ++ )
        {
            A[i][
0 =  A[i + 1 ][ 0 ];
            A[i][
1 =  A[i + 1 ][ 1 ];
        }

        
// 下一次计数的起始位置
        pos  =   out ;

        
// 人数减1
        n -- ;
    }
    
    cout 
<< " 最后一位离队的成员是 " << A[ 0 ][ 0 ] << " " << endl;
    
return ;
}
// 提供测试数据
int  A[ 7 ][ 2 =  
    {
        {
1 , 3 },{ 2 , 1 },{ 3 , 7 },{ 4 , 2 },{ 5 , 4 },{ 6 , 7 },{ 7 , 4 }
    };

2、二分查找法,我一直觉得二分查找法,是一种非常优美的方法,写起来非常漂亮:

//
// 二分查找法
//
// A[]:一个已经从小到大排好序的数组
// n:元素个数
// key:欲查找的关键码
// 如果找到,返回关键码所在的下标,否则返回n
int  binarySearch( int  A[],  int  n,  int  key)
{
    
// 数组边界
     int  left  =   - 1 ;    
    
int  right  =  n;    

    
// 当left == right-1时,边界中间已经没有元素了。
     while  (left  <  right - 1 )
    {
        
int  mid  =  (left  +  right) / 2 ;  // 中间点
         if  (key  <  A[mid])
            right 
=  mid;
        
if  (key  ==  A[mid])
            
return  mid;     // 找到了
         else  
            left 
=  mid;
    }

    
// 没有找到
     return  n;
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值