笔试题 1.3 百度 2012 10.09 程设 --B

1, 字符串左移,void *pszStringRotate(char *pszString, intnCharsRotate),比如ABCDEFG,移3位变DEFGABC,要求空间复杂度O(1),时间复杂度O(n)

void string_rotate(int shift){
        char obj_str[100] = "abcdefghijk";
        int leng = strlen(obj_str);
        if(leng  <= 0) return;
        int curr_pos = (0 + shift) % leng;
        int tmp_pos = curr_pos;
        do{
                printf("%c ", obj_str[tmp_pos]);
                tmp_pos = (tmp_pos + 1)%leng;
        }while(tmp_pos != curr_pos);
        printf("\n");
        return ;
}

空间复杂度满足了,而且,这里没有设计移动数据,算是偷懒了,只是对于位置记录信息做了改动;实际上如果要移动的话,做法就是类似于选择排序的做法;

2, 公司里面有1001个员工,现在要在公司里面找到最好的羽毛球选手,也就是第一名,每个人都必须参赛,问至少要比赛多少次才能够找到最好的羽毛球员工。

int match_times(int n){
        if(n == 1) return 0;
        return match_times(n/2+(n&0x01)) + n/2;
}

 3,有20个数组,每个数组有500个元素,并且是有序排列好的,现在在这20*500个数中找出排名前500的数

       (from http://blog.163.com/hhx_zju/blog/static/21547002820132791639932/ )

 

#include<iostream>
#include<cstdlib>
using namespace std;
const int N=20;
const int M=500;
int a[N][M];
int out_put[M];
int out_count=0;

void exchange1(int* (&a),int* (&b))
{
    int* temp;
    temp=a;
    a=b;
    b=temp;
}
void exchange(int &a,int &b)
{
    int temp;
    temp=a;
    a=b;
    b=temp;
}
void Adjustment(int* (&p)[N+1],int (&b)[N+1],int k)
{
    int n=N;
    for(;k<=n/2;k++)
    {
        if(2*k<n)
        {
            if((b[2*k]>=b[2*k+1])&&(b[2*k]>b[k]))
            {
                exchange(b[2*k],b[k]);
                exchange1(p[2*k],p[k]);
            }
            else if((b[2*k]<b[2*k+1])&&(b[2*k+1]>b[k]))
            {
                exchange(b[2*k+1],b[k]);
                exchange1(p[2*k+1],p[k]);
            }
        }
        else if(2*k==n)
        {
            if(b[2*k]>b[k])
            {
                exchange(b[2*k],b[k]);
                exchange1(p[2*k],p[k]);
            }
        }//else if
    }//for

}
void buildHeap(int* (&p)[N+1],int (&b)[N+1])
{
    int n=N;
    int k;
    for(k=n/2;k>=1;k--)
        Adjustment(p,b,k);
}

void max_k(int (&a)[N][M])
{
    int i=0,j=0;
    int* p[N+1];//
    int b[N+1];
    p[0]=NULL;
    b[0]=0;//
    for(i=1;i<=N;i++)
        p[i]=&a[i-1][M-1];
    for(i=1;i<N+1;i++)
        b[i]=a[i-1][M-1];
    ///////////////////
    buildHeap(p,b);

    out_put[out_count++]=*p[1];

    while(out_count<=M-1)
    {
        p[1]--;
        b[1]=*(p[1]);
        Adjustment(p,b,1);
        out_put[out_count++]=*p[1];
    }
}

void quickSort(int *a,int left,int right)
{
    if(left<right-1)
    {
        int mid=(right-left)/2+left;
    
        if(a[left]>a[mid])
            exchange(a[left],a[mid]);
        if(a[mid]>a[right])
            exchange(a[mid],a[right]);
        if(a[left]>a[mid])
            exchange(a[left],a[mid]);
        exchange(a[mid],a[right]);
    int lef=left-1;
    int rig=left;
    while(rig<=right-1)
    {
        if(a[rig]<a[right])
            exchange(a[++lef],a[rig]);
        rig++;
    }
    exchange(a[++lef],a[rig]);
    quickSort(a,left,lef-1);
    quickSort(a,lef+1,right);
    }
    else if(left==right-1)
    {
        if(a[left]>a[right])
            exchange(a[left],a[right]);
    }
}
int main()
{
    int i,j;
    //随机生成数据
    for(i=0;i<N;i++)
        for(j=0;j<M;j++)
            a[i][j]=rand()%256;
    //快速排序
    for(i=0;i<N;i++)
    {
        quickSort(a[i],0,M-1);
    }
    //得到前500个最大的数
    max_k(a);
    //输出结果
    for(i=0;i<M;i++)
    {
        cout<<out_put[i]<<" ";
        if((i+1)%N==0)
        {
            cout<<endl;
        }
    }
    cout<<endl;
    char c;
    cin>>c;
}

 

 4,现在有一个手机,手机上的键盘上有这样的对应关系,2对应"abc",3对应"def".....手机里面有一个userlist用户列表,当我们输入942的时候出来拼音的对应可能是“xia”,“zha”,“xi”,“yi”等,当我们输入9264的时候出来是yang,可能是“样”,“杨”,“往”等,现在我们输入一个字符串数字,比如926等,要在电话簿userlist中查找出对应的用户名和电话号码并返回结果。

   (from  http://www.linuxidc.com/Linux/2012-10/71974p2.htm )

#include <iostream>  
#include <cstdlib>  
#define N 4 //电话号码个数  
 
using namespace std; 
 
char c[][10] = {"","","ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ"};//存储各个数字所能代表的字符  
int number[N] = {2, 4 ,7, 9}; //存储电话号码  
int total[10] = {0, 0, 3, 3, 3, 3, 3, 4, 3, 4}; //各个数组所能代表的字符总数  
int answer[N]; //数字目前所代表的字符在其所能代表的字符集中的位置,初始为0  
 
void Search(int *number, int n); //非递归的办法  
void RecursiveSearch(int *number, int cur, char *ps, int n); //递归的办法 
int main() 
{ 
        //Search(number, N);  
        char ps[N+1] = {0}; 
        RecursiveSearch(number, 0, ps, N); 
        return 0; 
} 
 
 
void Search(int *number, int n) 
{ 
        int i; 
        while(1) 
        { 
                for(i=0; i<n; ++i) 
                        printf("%c", c[number[i]][answer[i]]); 
                printf("\n"); 
                int k = n-1;    //用k和while循环来解决扩展性问题,模拟了递归  
                while(k >= 0) 
                { 
                        if(answer[k] < total[number[k]]-1) 
                        { 
                                ++answer[k]; 
                                break; 
                        } 
                        else 
                        { 
                                answer[k] = 0; 
                                --k; 
                        } 
                } 
                if(k < 0) 
                        break; 
        } 
} 
 
/*递归的解法: number为存储电话号码的数组,pos为当前处理的数字在number中的下标,初始为0 
*ps为一外部数组,用于存放字母,n代表电话号码的长度(个数) 
* 此递归的方法好理解,比上面非递归的办法好写易懂 
* */ 
void RecursiveSearch(int *number, int pos, char *ps, int n) 
{ 
        int i; 
        for(i=0; i<total[number[pos]]; ++i) 
        { 
                ps[pos] = c[number[pos]][i]; 
                if(pos == n-1) 
                        cout<<ps<<endl; 
                else 
                        RecursiveSearch(number, pos+1, ps, n); 
        } 
} 

 

 

5, 在一维坐标轴上存在许多条线段,用最简单的算法找出重合长度最长得两条线段。比如线段A(1,5)、B(2,8)、C(3,9),则B和C的重合长度最长,为5  

       (from http://blog.163.com/hhx_zju/blog/static/21547002820132782440767/ )

    这里的做法是 两轮循环搜索,O(n^2)的时间复杂度,相类似的分析还可以参看 http://blog.csdn.net/xiaohui5319/article/details/7483888         

#include <iostream>
using namespace std;
const int N=3;

struct Node
{
    friend bool operator<(Node A,Node B);
public:
    Node(int x=0,int y=0):low(x),high(y)
    {}


    int low;
    int high;
};
bool operator<(Node A,Node B)
{
    return A.low<B.low;
}
int main()
{
    int i,k;
    int Max_Overlapping=0;
    int index=0;

    Node a[N]={Node(1,5),Node(2,8),Node(3,9)};
    //按照低端对数组进行排序,省略。
    for(i=0;i<N-1;)
    {
        for(k=i+1;a[i].high>a[k].high;k++)
        {
            if((a[k].high-a[k].low)>Max_Overlapping)
            {
                Max_Overlapping=a[k].high-a[k].low;
                index=k;
            }
        }
        if((a[i].high>a[k].low)&&((a[i].high-a[k].low)>Max_Overlapping))
        {
            Max_Overlapping=a[i].high-a[k].low;
            index=k;
        }
        if(index==i)
            i++;
        else
            i=index;
    }
    cout<<Max_Overlapping<<endl;

    char c;
    cin>>c;
}

 

       

posted on 2013-09-26 20:39  馒头山小八路  阅读(308)  评论(0编辑  收藏  举报

导航