一些招聘公司的笔试编程题

这一篇博文将会将近期写过的部分笔试程序题汇总到这里,将会不定期的更新。、、
/**
注意下面的所有的代码将主要是c语言的形式实现,假如需要会有部分c++代码。
为啥不用其他的高级语言,原因是我不会。
这些题目基本是招聘的笔试题,有的比较基础,有的比较烧脑。
*/


/*

  • 第一题


小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差的绝对值最小的有多少对呢?差的绝对值最大的呢?
输入描述:
输入包含多组测试数据。
对于每组测试数据:
N - 本组测试数据有n个数
a1,a2…an - 需要计算的数据
保证:
1<=N<=100000,0<=ai<=INT_MAX.

输出描述:
对于每组数据,输出两个数,第一个数表示差的绝对值最小的对数,第二个数表示差的绝对值最大的对数。
输入例子:
6
45 12 45 32 5 6
输出例子:
1 2

思路:先排序,在找最大最小的差值
下面是代码:
*/




#include"stdio.h"
#include"stdlib.h"

int cmp(const void *a,const void *b)
{
    /*设置有小到大的排序*/
        return (*(int *)a - *(int*)b);

}

int main()
{
    unsigned int i,j;
    unsigned int data[100000];
    unsigned int max_count=0;
    unsigned int min_count=0;
    unsigned int max=0;
    unsigned int min=0xffffffff;
    unsigned int num=0;
    unsigned int tmp;
    unsigned int resault_max;
    unsigned int resault_min;
    unsigned int count;


    while(scanf("%d",&num)!= EOF){


        for(i=0;i<num;i++){
            scanf("%d",(data+i));
        }
/*
    下面是用快速排序法实现的排序,对于快速排序法,其算法的复杂度为O(nlogn)比冒泡排序法复制度(O(n^2))要好,这里刚一开始使用的冒泡,由于复杂度太大,腾讯竟然提示超时。。无语。

*/
        qsort(data,num,sizeof(int),cmp);

        /*
        在这里因为要进行多次循环,每次循环前都应该给予初值,不然将导致结果出错。
        */
        resault_max=1;
        resault_min=1;
        max=0;
        min=0xffffffff;
/*
下面是找最小值,顺便把最大差值也计算出来。
*/
        for(i=0;i<num-1;i++){
            tmp=data[i+1]-data[i];

            if(min>tmp)
                min=tmp;      

            if(data[i+1]==data[0])
                resault_min++;
            if(data[i]==data[num-1])
                resault_max++;

        }
        /*
        同样,由于多次循环 ,每次都要赋予初值
        */
        count=1;
        min_count=0;
        /*
    下面是找到差值最小的个数
    个数的计算方式,将最小差值的组合个数用C(2/3)的形式计算。  
    */
        for(i=0;i<num-1;i++){
            tmp=data[i+1]-data[i];
            if(tmp==min)
                count++;
            else{
                if(count>1)
                    min_count+=count*(count-1)/2;
                count=1;
            }
        }
        if(count>1)
        min_count+=count*(count-1)/2;

        printf("%d %d\n",min_count,resault_min*resault_max);
    }
}

/*

  • 第二题


输入任意时间,输出改时刻的下一秒:

例如输入2008年2月28日23时59分59秒,
输出为:2008年2月29日0时0分0秒。
输入一个时间,输出下一秒的时间。
例如输入2008年2月28日23时59分59秒,
输出为:2008年2月29日0时0分0秒。
*/



#include"stdio.h"
#include
#include"string.h"
#include"assert.h"
void main(int argc,int *argv[])
{
    int year     =atoi(argv[1]);
    int month    =atoi(argv[2]);
    int day      =atoi(argv[3]);
    int hour     =atoi(argv[4]);
    int minute   =atoi(argv[5]);
    int second   =atoi(argv[6]);
    printf("%d:%d:%d:%d:%d:%d \n",year,month,day,hour,minute,second);

    updata(&year,&month,&day,&hour,&minute,&second);
    printf("%d:%d:%d:%d:%d:%d \n",year,month,day,hour,minute,second);

}

inline int updata(int *year,int *month,int *day,int *hour,int *minute,int *second)
{
    *second+=1;
    if(*second<60)
        return 0;
    else{
        *second=0;
        *minute+=1;
        if(*minute<60)
            return 0;
        else{
            *minute=0;
            *hour +=1;
            if(*hour<24)
                return 0;
            else{
                *hour=0;
                *day+=1;
                switch(*month)
                {
                    case  1:
                    case  3:
                    case  5:
                    case  7:
                    case  8:
                    case 10:
                    case 12:
                            if(*day<32)
                                return 0;
                            else{
                                *day   =1;
                                *month+=1;
                                if(*month<13)
                                    return 0;
                                else{
                                    *month=1;
                                    *year+=1;
                                    return 0;
                                }
                            }
                    case  4:
                    case  6:
                    case  9:
                    case 11:
                            if(*day<31)
                                return 0;
                            else{
                                *day   =1;
                                *month+=1;
                                return 0;
                            }
                    case 2:
                            if((*year%4==0&&*year0!=0)||*year@0==0){

                                if(*day<29)
                                    return 0;
                                else{
                                    *day   =1;
                                    *month+=1;
                                    return 0;
                                }

                            }else{

                                if(*day<30)
                                    return 0;
                                else{
                                    *day   =1;
                                    *month+=1;
                                    return 0;
                                }

                            }
                    default:return -1;
                }
            }
        }
    }
}

/*

  • 第三题:

小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?

输入描述:

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.

输出描述:

对于每组数据,输出移位后的字符串。

输入例子:
AkleBiCeilD

输出例子:
kleieilABCD
*/


#include"stdio.h"
#include"string.h"

#define MAX_LENGTH 1000

int main()
{
    char data[MAX_LENGTH]={0};
    char lower[MAX_LENGTH]={0};
    char upper[MAX_LENGTH]={0};
  /*
  腾讯总是这么规定,要可以循环处理
  */
    while(scanf("%s",&data)!= EOF){

        int num=strlen(data);
        char *p_up =upper;
        char *p_low=lower;
        /*
    将大写小字母放到不同的数组里面
        */
        for(int i=0;i<num;i++){
            if(data[i]>='a'&& data[i]<='z')
               *p_low++=data[i];
            else
               *p_up++ =data[i];
        }
        /*
        将大小写字母数组从新复制到data数组里面
        */
        num=strlen(lower);
        strncpy(data,lower,num);
        strncpy(data+num,upper,strlen(upper));  
/*
由于前面使用了while,这里打印的时候一定要用\n,不然很可能出现莫名其妙的问题。打印完毕后要清空,以便下次循环继续使用。
*/
        printf("%s\n",data);

        memset(data, 0 , sizeof(data));
        memset(lower, 0 , sizeof(lower));
        memset(upper, 0 , sizeof(upper));      

    }

}

**

  • 第四题


给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
输入描述:
输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.

输出描述:
对于每组数据,输出一个整数,代表最少需要删除的字符个数。
输入例子:
abcda
google
输出例子:
2
2

思路:这里确实看了没什么思路,还有看到有人提示说直接用文本比较好,非常感谢“万仓一黍”的博客:
http://www.cnblogs.com/grenet/archive/2010/06/03/1750454.html
这里使用的是Needleman/Wunsch算法 ,原理上面的博文说的很明白。
**

#include"stdio.h"
#include"math.h"
#include"string.h"

#define MAX_LENGTH 1000

#define max(n,j) ((n)>(j)?(n):(j))

int main()
{
    char  data[MAX_LENGTH]={0};
    /*
    下面这个定义一定要是int型,千万不要是char类型,当时少于255个数据还好,不过腾讯测试的时候,可能是几百个数据,用char类型的数据会导致溢出,
    */
    unsigned int  judge_arr[MAX_LENGTH+1][MAX_LENGTH+1]={0};
    int i,j;

    while(scanf("%s",data)!=EOF){
        int length=strlen(data);
/*下面Needleman/Wunsch算法,进行比较文本 */
        for( i=0;i<length;i++){
            for(j=0;j<length;j++){
                if(data[i]==data[length-1-j])
                        judge_arr[i+1][j+1]= judge_arr[i][j]+1;
                else
                    judge_arr[i+1][j+1]=max(judge_arr[i][j],\
                                        max(judge_arr[i+1][j],\
                                        judge_arr[i][j+1]));;
            }
        }
/*同理,打印需要加上'\n',不然提示错误*/
        printf("%d\n",length-judge_arr[length][length]);
/*为了循环测试,相互不影响,清空。*/
        memset(data,0,sizeof(data));
        memset(judge_arr,0,sizeof(judge_arr));
    }
}
  • 第五题:
    拉姆刚开始学习英文单词,对单词排序很感兴趣。
    如果给拉姆一组单词,他能够迅速确定是否可以将这些单词排列在一个列表中,使得该列表中任何单词的首字母与前一单词的为字母相同。
    你能编写一个程序来帮助拉姆进行判断吗?

输入描述:

输入包含多组测试数据。

对于每组测试数据,第一行为一个正整数n,代表有n个单词。

然后有n个字符串,代表n个单词。

保证:

2<=n<=200,每个单词长度大于1且小于等于10,且所有单词都是由小写字母组成。

输出描述:
对于每组数据,输出”Yes”或”No”

输入例子:
3
abc
cdefg
ghijkl
4
abc
cdef
fghijk
xyz

输出例子:
Yes
No

#include"stdio.h"
#include"string.h"

#define MAX_N  200
#define MAX_LENGTH 11

int main()
{
    char data[MAX_N][MAX_LENGTH]={0};
    int num;
    int i;
    while(scanf("%d",&num)!=EOF){
        for(i=0;i<num;i++)
            scanf("%s",data[i]);
        char *p;
        char *next;
        int length;
        for(i=0;i<num-1;i++){
            p=data[i];
            next=data[i+1];
            length=strlen(p);
            p+=length-1;
            if(*p==*next)/*相等就直接进行下次判断*/
                continue;
            else{
                printf("No\n"); 
                goto flag;/*错误就直接跳出*/
            }               
        }
        printf("Yeo\n");
 flag:
        memset(data,0,sizeof(data));           

    }

}
  • 第六题:

题目描述

计算字符串最后一个单词的长度,单词以空格隔开。

输入描述:
一行字符串,非空,长度小于5000。

输出描述:
整数N,最后一个单词的长度。

输入例子:
hello world

输出例子:
5


#include"stdio.h"
#include"string.h"
int main(void)
{
    char s[5000]={0};
    //唯一要注意的就是空格的输入的问题,下面两句都可以实现。
    while (scanf("%[^\n]",s)!=NULL){
  //while (gets(s)!=NULL){
        int num=strlen(s);
        int sum=0;
        int i;
        for(i=num;(i>0)&&(s[i-1]!=' ');i--)
            sum++;
        printf("%d\n",sum);
        memset(s,'\0',num);
    }
    return 0;

}
  • 第七题:
    老师想知道从某某同学当中,分数最高的是多少,现在请你编程模拟老师的询问。当然,老师有时候需要更新某位同学的成绩.
    输入描述:

输入包括多组测试数据。
每组输入第一行是两个正整数N和M(0 < N <= 30000,0 < M < 5000),分别代表学生的数目和操作的数目。
学生ID编号从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩
接下来又M行,每一行有一个字符C(只取‘Q’或‘U’),和两个正整数A,B,当C为’Q’的时候, 表示这是一条询问操作,他询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少
当C为‘U’的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。

输出描述:

对于每一次询问操作,在一行里面输出最高成绩.

输入例子:

5 7
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 4 5
U 2 9
Q 1 5

输出例子:

5
6
5
9

#include"stdio.h"
#include"string.h"
#include"stdlib.h"


int main()
{
    unsigned int N;
    unsigned int M;
    char *grade;
    char c;
    unsigned int num1,num2;
    while(scanf("%d%d",&N,&M)!=EOF){
    //下面这里不知为何要多申请两个字节,不然提示溢出。
        grade=(char *)malloc(sizeof(char)*N+2);
        for(int i=0;i<N;i++){
            scanf("%d",(grade+i));
        }



         for(int j=0;j<M;j++){
         //关键在这里,注意前面%c之前的空格,必须要加,不然%c会吧一些空格、换行符等当成字符输入。
            scanf(" %c%d %d",&c,&num1,&num2);
         if(c=='Q'){
              int max=-1;
             if(num1>num2){
                int tmp=num1;
                num1=num2;
                num2=tmp;
             }
             for(int i=num1-1;i<num2;i++){
                 if(max<*(grade+i))
                      max=*(grade+i);
                  }
                printf("%d\n",max);
            }else{
                *(grade+num1-1)=num2;
            }

        }
        free(grade);



    }
}

题目描述

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

class Solution {
public:
    double Power(double base, int exponent) {
        int num=abs(exponent);
        double result = base;
        if(exponent==0)
            return 1;
        if(base>-0.0000001&&base<0.0000001)
            return 0;
        else{
            while(--num)
                result *= base;  
        }
        if(exponent<0)
            return (double)1/result;
        return result;
    }
};

题目描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

分析:
这个主要是其中的一个要不其他数字出现的和还要多,
所以,设置计数器,当遇到相等的计数器加1,不相等的减去1.当为零的时候重新选择标本。

public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        if(numbers.empty())
            return 0;

        int i=0;
        int result=numbers[0];
        int count=1;
        while(i<numbers.size()){
            if(count == 0){
                result = numbers[i];
                count  = 1;
            }else{
                if(numbers[i] == result)
                    count++;
                else 
                    count--;
            }
            i++;

        }
        /*
        下面有个易错点,比如为何不能写成:
         if(count>1)
            return result;
        else
            return 0;
       实在想不明白的话就想想 121

        */
        count = 0;
        while(i--){
            if(result == numbers[i])
                count++;
        }
        if(count*2>numbers.size())
            return result;
        else
            return 0;

    }
};

题目描述

统计一个数字在排序数组中出现的次数。
分析:看着就是二分法吧

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        if(data.empty())
            return 0;

         return find_data(data,k,0,data.size());  

    }
    int find_data(vector<int> data ,int k,int start,int end){

        if (start>end)
            return 0;
        int middle_sit    = (end+start)/2;
        int middle_value = data[middle_sit];
        if(middle_value == k){
            int count =0;
            int sit = middle_sit;
            while(data[sit] == k){
                count++;
                if(sit==0)
                    break;
                sit--;

            }
            sit = middle_sit;
            while(data[sit] == k){
                count++;
                if(sit==data.size())
                    break;
                sit++;
            }
            return (count-1);


        }
        if(middle_value < k)
            start = middle_sit + 1;
        if(middle_value > k)
            end = middle_sit - 1;
        return find_data(data ,k , start, end);


    }

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值