百度2014校招笔试题目题解(更新了第1题的算法,10.9下午) .

百度2014校招笔试题目题解

                                                                     ----武汉站,9.28号百度校招笔试题目算法题目部分

二、算法与程序设计题

1、给定任意一个正整数,求比这个数大且最小的“不重复数”,“不重复数”的含义是相邻两位不相同,例如1101是重复数,而1201是不重复数。(15分)

2、长度为N(N很大)的字符串,求这个字符串里的最长回文子串。(15分)

3、数轴上从左到右有n各点a[0], a[1], ……,a[n -1],给定一根长度为L的绳子,求绳子最多能覆盖其中的几个点。(15分)

 

这是百度的笔试题目,好像是什么系统行为分析师职位的笔试题目!博文最后会贴出试题照片!

 

题解:(题解非官方,仅供参考,转载请联系博主,有错误的地方望指正!谢谢)

1、给定任意一个正整数,求比这个数大且最小的“不重复数”,“不重复数”的含义是相邻两位不相同,例如1101是重复数,而1201是不重复数。

解: 这道题目我也没有什么特别出彩的算法,就是按照常规思路来求解,首先要理解什么叫做“不重复数”,这是解题的关键之一,相邻两位不相同的数即为“不重复数”;还有一个地方要注意的就是“求比这个数大且最小的”,就是在比给定数大的不重复数中找到最小的!理解了这两个地方,这道题目就可以着手求解了!

  我用一个实例来说说我的思路,假如给定的正整数为11233:

  用最常规的方法,就是每次对这个数加1,判断是不是“不重复数”,加1后为11234,有两个1重复了,于是继续加1,……,那么主要就在判断是不是“不重复数”上面了,我设置了两个变量,是currentBit, lastBit,顾名思义,lastBit保存上一个数位的值,currentBit保存当前数位的值,拿整数12345来说,就是初始化lastBit = 5,然后计算currentBit = 4;下一步,把currentBit 值赋给lastBit,即lastBit = 4,计算currentBit  = 3;依次类推。

  说到这里,很多朋友觉得可以有更加高效的方法,小难点有4:

  1、因为可以直接定位到“重复”的数位的位置,比如12344,我们可以直接定位到个位数4和十位数4上面,然后在低数(这里就是个位数)上加1即可,事实上,不是如此简单,假设是对整数12199呢?还能简单的加1操作吗,加1之后结果为12200,那结果显然是错的,当然这也是可以处理的,处理方法就是把12200继续拿到循环去处理,再判断是不是“不重复数”;

  2、这里又产生一个问题,因为“重复“的数位可能不止一对,有可能有多对,比如整数11233,定位“33”之后变为“34”,定位“11”之后变为“12”,结果就是12234。又有重复的地方,就是“22”。继续拿到循环去重复;

  3、还有要注意的是,你的程序的设计,是如何存储数位的值的,是一个一个数位的值求出来呢?还是像我这样设置一个前后索引?把每个数位的值求出来并且存储,程序会变得繁琐复杂,不易读懂,如果是设置前后索引,则要注意程序退出循环的条件!

  4、对于存在多对“重复”数位的正整数,数位“重复”的定位和变换,是从高位到低位,还是从低位到高位呢?正确的应该是从高位到低位,这给我们的程序设计也带来了不便。

  这些就是我在试图找到高效算法时得到的经验,每个小难点都要处理,有点繁琐,有耐心的朋友,可以试着写一下更高效的算法,另外,使用了比较高效的算法,代码尽量保持简洁,并告知博主,谢谢!

  my code:(简单加1的方法)

  1. /* 
  2.     给定任意一个正整数,求比这个数大且最小的“不重复数”,“不重复数的含义是相邻两位不相同,例如1101是不重复数” 
  3.  
  4. */  
  5. #include <stdio.h>   
  6. #include <stdlib.h>   
  7. int getNumNonrepetition(const int NumGived)  
  8. {  
  9.     int flag = 0;//为0表示该数不是“不重复数”   
  10.     int numRepeat = NumGived;  
  11.     int numTemp = 0;//   
  12.     int currentBit = 0, lastBit = 0;//前后数位索引   
  13.     while(1)  
  14.     {  
  15.         numRepeat++;  
  16.         //初始化后索引   
  17.         numTemp = numRepeat;  
  18.         lastBit = numTemp % 10;  
  19.         numTemp /= 10;  
  20.         flag = 1;  
  21.         //判断该数是不是“非重复数”   
  22.         while(numTemp != 0)  
  23.         {  
  24.             currentBit = numTemp % 10;  
  25.             numTemp /= 10;  
  26.             if(lastBit == currentBit)  
  27.             {  
  28.                 flag = 0;  
  29.                 break;  
  30.             }  
  31.             lastBit = currentBit;  
  32.         }  
  33.         if(flag == 1)//该数为不重复数,返回   
  34.         {  
  35.             return numRepeat;  
  36.         }  
  37.     }  
  38. }  
  39. int main(void)  
  40. {  
  41.     int NumGived = 19922884;  
  42.     int result = getNumNonrepetition(NumGived);  
  43.     printf("the number is %d\n", result);  
  44.     return 0;  
  45. }  
/*
    给定任意一个正整数,求比这个数大且最小的“不重复数”,“不重复数的含义是相邻两位不相同,例如1101是不重复数”

*/
#include <stdio.h>
#include <stdlib.h>
int getNumNonrepetition(const int NumGived)
{
    int flag = 0;//为0表示该数不是“不重复数”
    int numRepeat = NumGived;
    int numTemp = 0;//
    int currentBit = 0, lastBit = 0;//前后数位索引
    while(1)
    {
        numRepeat++;
        //初始化后索引
        numTemp = numRepeat;
        lastBit = numTemp % 10;
        numTemp /= 10;
        flag = 1;
        //判断该数是不是“非重复数”
        while(numTemp != 0)
        {
            currentBit = numTemp % 10;
            numTemp /= 10;
            if(lastBit == currentBit)
            {
                flag = 0;
                break;
            }
            lastBit = currentBit;
        }
        if(flag == 1)//该数为不重复数,返回
        {
            return numRepeat;
        }
    }
}
int main(void)
{
    int NumGived = 19922884;
    int result = getNumNonrepetition(NumGived);
    printf("the number is %d\n", result);
    return 0;
}


更新内容:(10.9号下午)

简单加1的算法,效率太低,看到这么多的朋友的评论,大家的算法大同小异,我也写了一个算法,拿出来和大伙分享。

算法:

1、把整数放到字符数组里面去,从高位为低位(用变量i)扫描,找到重复的数位,重复数位为“99”跳到第2步,否则跳到第3步,若没有重复的数位,则该数为不重复数,返回;

2、遇到“99”的重复数,则把“99”改为“00”,然后在“99”前面一位字符加1,把扫描的地方定位在“99”往高位方向的第2位,比如是1299,变换后为1300,然后把扫描变量 i 定位在1这一数位上,返回第1步;

3、遇到非“99”的重复数,则直接在低位加1,后面依次变为010101……,结果就是最小的不重复数,返回改值;

至于前面说的一些难点,真是害怕误导了大家,毕竟总有考虑不到的地方,希望见谅!

code:(高效)

  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <string.h>   
  4. #define SIZE 100   
  5. int getNumNonrepetition(const long long  NumGived, char NumStr[])  
  6. {  
  7.     int NumTmp = NumGived;  
  8.     int NumLength = 0;  
  9.     int i = SIZE - 1;  
  10.     //把整数放到字符数组里面去,从后往前放,比如1234,   
  11.     //那么数组NumStr[96] = 1  NumStr[97] = 2  NumStr[98] = 3  NumStr[99] = 4, SIZE = 100   
  12.     do  
  13.     {  
  14.         NumStr[i] = NumTmp % 10 + '0';  
  15.         NumTmp /= 10;  
  16.         i--;  
  17.     }while(NumTmp != 0);  
  18.     NumLength = SIZE - i - 1;//计算整数的位数   
  19.   
  20.     int flag = 0;//设置010101的时候用的变量   
  21.     i = SIZE - NumLength;  
  22.     while( 1 )  
  23.     {  
  24.         //定位到重复的位上面,下标i + 1为低位,此时NumStr[i] == NumStr[i + 1]   
  25.         while(i + 1 < SIZE && NumStr[i] != NumStr[i + 1]) i++;  
  26.         if(i == SIZE - 1) break;//扫完一遍,没有重复的,跳出循环,该数是不重复数   
  27.   
  28.         if(NumStr[i + 1] == '9')//重复的数位为99这种情况,将这两位全部置0,高位加1   
  29.         {  
  30.             NumStr[i + 1] = '0';  
  31.             i--;  
  32.             NumStr[i + 1] = '0';  
  33.             i--;  
  34.             NumStr[i + 1] += 1;  
  35.         }  
  36.         else//重复的   
  37.         {  
  38.             //低位加1   
  39.             NumStr[i + 1] += 1;  
  40.             i += 2;  
  41.             flag = 0;  
  42.             //后续全部设为0101……,这个时候肯定是不重复数了,所以可以跳出循环   
  43.             while( i < SIZE )  
  44.             {  
  45.                 NumStr[i] = flag % 2+ '0';  
  46.                 flag++;  
  47.                 i++;  
  48.             }  
  49.             break;  
  50.         }  
  51.     }  
  52.     //打印最小的”不重复数“   
  53.     int start = SIZE - NumLength;  
  54.     //如果是99开头的数字,高位可能会进位,判断是否为零,不为零则有进位,需打印出来   
  55.     if(NumStr[start - 1] != '0') putchar(NumStr[start - 1]);  
  56.     for(i = start; i < SIZE; i++ )  
  57.     {  
  58.         putchar(NumStr[i]);  
  59.     }  
  60.     return 0;  
  61. }  
  62. int main(void)  
  63. {  
  64.     long long  NumGived = 119998989;  
  65.     char NumStr[SIZE];  
  66.     memset(NumStr, '0', SIZE * sizeof(char));  
  67.     getNumNonrepetition(NumGived, NumStr);  
  68.     return 0;  
  69. }  
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 100
int getNumNonrepetition(const long long  NumGived, char NumStr[])
{
    int NumTmp = NumGived;
    int NumLength = 0;
    int i = SIZE - 1;
    //把整数放到字符数组里面去,从后往前放,比如1234,
    //那么数组NumStr[96] = 1  NumStr[97] = 2  NumStr[98] = 3  NumStr[99] = 4, SIZE = 100
    do
    {
        NumStr[i] = NumTmp % 10 + '0';
        NumTmp /= 10;
        i--;
    }while(NumTmp != 0);
    NumLength = SIZE - i - 1;//计算整数的位数

    int flag = 0;//设置010101的时候用的变量
    i = SIZE - NumLength;
    while( 1 )
    {
        //定位到重复的位上面,下标i + 1为低位,此时NumStr[i] == NumStr[i + 1]
        while(i + 1 < SIZE && NumStr[i] != NumStr[i + 1]) i++;
        if(i == SIZE - 1) break;//扫完一遍,没有重复的,跳出循环,该数是不重复数

        if(NumStr[i + 1] == '9')//重复的数位为99这种情况,将这两位全部置0,高位加1
        {
            NumStr[i + 1] = '0';
            i--;
            NumStr[i + 1] = '0';
            i--;
            NumStr[i + 1] += 1;
        }
        else//重复的
        {
            //低位加1
            NumStr[i + 1] += 1;
            i += 2;
            flag = 0;
            //后续全部设为0101……,这个时候肯定是不重复数了,所以可以跳出循环
            while( i < SIZE )
            {
                NumStr[i] = flag % 2+ '0';
                flag++;
                i++;
            }
            break;
        }
    }
    //打印最小的”不重复数“
    int start = SIZE - NumLength;
    //如果是99开头的数字,高位可能会进位,判断是否为零,不为零则有进位,需打印出来
    if(NumStr[start - 1] != '0') putchar(NumStr[start - 1]);
    for(i = start; i < SIZE; i++ )
    {
        putchar(NumStr[i]);
    }
    return 0;
}
int main(void)
{
    long long  NumGived = 119998989;
    char NumStr[SIZE];
    memset(NumStr, '0', SIZE * sizeof(char));
    getNumNonrepetition(NumGived, NumStr);
    return 0;
}



 

2、长度为N(N很大)的字符串,求这个字符串里的最长回文子串。

解:题目指出“N很大”,就是提示我们不要想通过遍历的方法来找到这个字符串,我想到的就一种解法,时间复杂度应该不高,但是我算不出来这个算法的复杂度是多少,首先说一下什么是回文字符串:回文字符串是指从左到右和从右到左相同的字符串,比如"1221"或者“12321”都是回文字符串。刚好举得这两个回文字符串的例子就是我的算法的两个类别:

  第一类“12321”:中间是一个单独的字符。算法的思想是从第2个字符直到倒数第2个字符遍历,每遇到一个字符,就依次判断这个字符前后的字符是否相等,如果相等,则继续判断下一个字符,直到以这个字符为中心的两边对称的字符不相等为止,或者前后字符的位置数组越界为止;计算此时的回文字符串的长度,与之前的比较,记下较长的回文字符串的长度和中心字符的位置;遍历结束则返回最大长度和中心字符的位置

  图示:若字符串为“1234321”

 

   第二类“123321”:中间是两个相同的字符。算法思想同上,其实是一样的过程!图解也是一样的!

my code:

 

  1. /* 
  2.     长度为N(N很大)的字符串,求这个字符串里的最长回文子串。 
  3. */  
  4. #include <stdio.h>   
  5. #include <stdlib.h>   
  6. #include <string.h>   
  7. //第一类“12321”:中间是一个单独的字符   
  8. int  FindLongPaliSubstr_Odd(const char A[], int * indexMid)  
  9. {  
  10.     int i = 0, cnt = 0;//cnt表示前后移动位数   
  11.     int MyMax = 0;  
  12.     int lenOfA = strlen(A);  
  13.     *indexMid = 0;  
  14.     for(i = 1; i <= lenOfA - 2; i++)  
  15.     {  
  16.         cnt = 0;  
  17.         while(i - cnt >= 0 && i + cnt <= lenOfA - 1 && A[i - cnt] == A[i + cnt])  
  18.         {  
  19.             cnt++;  
  20.         }  
  21.         cnt--;  
  22.         //找到较大长度的回文字符串,保存中心字符的位置   
  23.         if(MyMax < 2 * cnt + 1)  
  24.         {  
  25.             MyMax = 2 * cnt + 1;  
  26.             *indexMid = i;  
  27.         }  
  28.     }  
  29.     return MyMax;  
  30. }  
  31. //第二类“12321”:中间是两个相同的字符。   
  32. int  FindLongPaliSubstr_Even(const char A[],int * First)  
  33. {  
  34.     int i = 0, cnt = 0;//cnt表示前后移动位数   
  35.     int MyMax = 0;  
  36.     int lenOfA = strlen(A);  
  37.     *First = 0;//中间两个相同字符的第一个字符位置   
  38.     for(i = 0; i <= lenOfA - 2; i++)  
  39.     {  
  40.         if(A[i] == A[i + 1])  
  41.         {  
  42.             cnt = 1;  
  43.             while(i - cnt >= 0 && (i + 1 + cnt) <= lenOfA - 1 && A[i - cnt] == A[i + 1 + cnt])  
  44.             {  
  45.                 cnt++;  
  46.             }  
  47.             cnt--;  
  48.             //找到较大长度的回文字符串,保存中心第一个字符的位置   
  49.             if(MyMax < 2 * cnt + 2)  
  50.             {  
  51.                 MyMax = 2 * cnt + 2;  
  52.                 *First = i;  
  53.             }  
  54.         }  
  55.     }  
  56.     return MyMax;  
  57. }  
  58.   
  59. int main(void)  
  60. {  
  61.     char A[] = "adfadfbadfdg12321fagage";  
  62.     int indexMid = 0;  
  63.     int First = 0;  
  64.     int i = 0;  
  65.     //两种类别的最长回文子串的长度   
  66.     int MaxOdd = FindLongPaliSubstr_Odd(A, &indexMid);  
  67.     int MaxEven = FindLongPaliSubstr_Even(A, &First);  
  68.   
  69.     printf("indexMid = %d\n", indexMid);  
  70.     printf("First = %d\n", First);  
  71.     //哪类比较大,输出哪一类的回文子串   
  72.     if( MaxOdd > MaxEven)  
  73.     {  
  74.         for(i = indexMid - (MaxOdd - 1) / 2; i <= indexMid + (MaxOdd - 1) / 2; i++)  
  75.         {  
  76.             putchar(A[i]);  
  77.         }  
  78.     }  
  79.     else  
  80.     {  
  81.         for(i = First - (MaxEven - 2) / 2; i <= First + 1 + (MaxEven - 2) / 2; i++)  
  82.         {  
  83.             putchar(A[i]);  
  84.         }  
  85.     }  
  86.     return 0;  
  87. }  
/*
    长度为N(N很大)的字符串,求这个字符串里的最长回文子串。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//第一类“12321”:中间是一个单独的字符
int  FindLongPaliSubstr_Odd(const char A[], int * indexMid)
{
    int i = 0, cnt = 0;//cnt表示前后移动位数
    int MyMax = 0;
    int lenOfA = strlen(A);
    *indexMid = 0;
    for(i = 1; i <= lenOfA - 2; i++)
    {
        cnt = 0;
        while(i - cnt >= 0 && i + cnt <= lenOfA - 1 && A[i - cnt] == A[i + cnt])
        {
            cnt++;
        }
        cnt--;
        //找到较大长度的回文字符串,保存中心字符的位置
        if(MyMax < 2 * cnt + 1)
        {
            MyMax = 2 * cnt + 1;
            *indexMid = i;
        }
    }
    return MyMax;
}
//第二类“12321”:中间是两个相同的字符。
int  FindLongPaliSubstr_Even(const char A[],int * First)
{
    int i = 0, cnt = 0;//cnt表示前后移动位数
    int MyMax = 0;
    int lenOfA = strlen(A);
    *First = 0;//中间两个相同字符的第一个字符位置
    for(i = 0; i <= lenOfA - 2; i++)
    {
        if(A[i] == A[i + 1])
        {
            cnt = 1;
            while(i - cnt >= 0 && (i + 1 + cnt) <= lenOfA - 1 && A[i - cnt] == A[i + 1 + cnt])
            {
                cnt++;
            }
            cnt--;
            //找到较大长度的回文字符串,保存中心第一个字符的位置
            if(MyMax < 2 * cnt + 2)
            {
                MyMax = 2 * cnt + 2;
                *First = i;
            }
        }
    }
    return MyMax;
}

int main(void)
{
    char A[] = "adfadfbadfdg12321fagage";
    int indexMid = 0;
    int First = 0;
    int i = 0;
    //两种类别的最长回文子串的长度
    int MaxOdd = FindLongPaliSubstr_Odd(A, &indexMid);
    int MaxEven = FindLongPaliSubstr_Even(A, &First);

    printf("indexMid = %d\n", indexMid);
    printf("First = %d\n", First);
    //哪类比较大,输出哪一类的回文子串
    if( MaxOdd > MaxEven)
    {
        for(i = indexMid - (MaxOdd - 1) / 2; i <= indexMid + (MaxOdd - 1) / 2; i++)
        {
            putchar(A[i]);
        }
    }
    else
    {
        for(i = First - (MaxEven - 2) / 2; i <= First + 1 + (MaxEven - 2) / 2; i++)
        {
            putchar(A[i]);
        }
    }
    return 0;
}


 

3、数轴上从左到右有n各点a[0], a[1], ……,a[n -1],给定一根长度为L的绳子,求绳子最多能覆盖其中的几个点。

解:我对第3题的题解也是很常规,就是把相邻两个点的距离求出来,保存在一个数组arr[N]里面,从头到尾遍历数组arr[N],和直接选择排序差不多,写两个for循环,第一个for循环(外循环)中计数器 i 表示连续线段的起点,第二个for循环(内循环)的计数器 j 从 (i + 1)开始,依次累加Sum,若Sum > L,则记录点的个数(j - i)中的较大值max;其中,外循环,只要遇到的数比L大,就continue,内循环,只要遇到的数比L大,就break,这是因为长度为L的绳子是不可能覆盖这些点的,可以直接跳过!

如图:

my code:

 

  1. /* 
  2.     数轴上从左到右有n个点a[0],a[1],...,a[n - 1],给定一根长度为L的绳子,求绳子最多能覆盖其中几个点。 
  3.  
  4. */  
  5.   
  6. #include <stdio.h>   
  7. #include <stdlib.h>   
  8. #include <string.h>   
  9. #define N 8   
  10. int MaxTimesOfL(int A[], int L)  
  11. {  
  12.     int i = 0, j = 0;  
  13.     int *arr = (int *)malloc(sizeof(int) * (N - 1));  
  14.     memset(arr, 0, sizeof(int) * (N - 1));  
  15.     //初始化数组arr,两点间的距离为一个数组元素   
  16.     for(i = 0; i < N - 1; i++)  
  17.     {  
  18.         arr[i] = A[i + 1] - A[i];  
  19.     }  
  20.     //输出该数组   
  21.     for(i = 0; i < N - 1; i++)  
  22.     {  
  23.         printf("%-3d", arr[i]);  
  24.     }  
  25.   
  26.     int MaxTimes = 0;  
  27.     int Sum = 0;  
  28.     //遍历找到覆盖的最多点数   
  29.     for(i = 0; i < N; i++)  
  30.     {  
  31.         if(arr[i] > L)//遇到比L大的数则跳过   
  32.         {  
  33.             continue;  
  34.         }  
  35.         Sum = arr[i];  
  36.         for(j = i + 1; j < N - 1; j++)  
  37.         {  
  38.             if(arr[j] > L)//遇到比L大的数则跳过,这一句对于程序来说加与不加都一样   
  39.             {  
  40.                 break;  
  41.             }  
  42.             Sum += arr[j];  
  43.             if(Sum > L)  
  44.             {  
  45.                 break;  
  46.             }  
  47.         }  
  48.         MaxTimes = (MaxTimes > (j - i)) ? MaxTimes : (j - i);  
  49.     }  
  50.     return (MaxTimes + 1);//因为是线段,所以要加1表示覆盖的点数   
  51. }  
  52. int main(void)  
  53. {  
  54.     int A[] = {-1, 0, 3, 9, 11, 13, 14, 25};  
  55.     int L = 5;  
  56.     int result = MaxTimesOfL(A, L);  
  57.     printf("\nthe max times is %d\n", result);  
  58.     return 0;  
  59. }  
/*
    数轴上从左到右有n个点a[0],a[1],...,a[n - 1],给定一根长度为L的绳子,求绳子最多能覆盖其中几个点。

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 8
int MaxTimesOfL(int A[], int L)
{
    int i = 0, j = 0;
    int *arr = (int *)malloc(sizeof(int) * (N - 1));
    memset(arr, 0, sizeof(int) * (N - 1));
    //初始化数组arr,两点间的距离为一个数组元素
    for(i = 0; i < N - 1; i++)
    {
        arr[i] = A[i + 1] - A[i];
    }
    //输出该数组
    for(i = 0; i < N - 1; i++)
    {
        printf("%-3d", arr[i]);
    }

    int MaxTimes = 0;
    int Sum = 0;
    //遍历找到覆盖的最多点数
    for(i = 0; i < N; i++)
    {
        if(arr[i] > L)//遇到比L大的数则跳过
        {
            continue;
        }
        Sum = arr[i];
        for(j = i + 1; j < N - 1; j++)
        {
            if(arr[j] > L)//遇到比L大的数则跳过,这一句对于程序来说加与不加都一样
            {
                break;
            }
            Sum += arr[j];
            if(Sum > L)
            {
                break;
            }
        }
        MaxTimes = (MaxTimes > (j - i)) ? MaxTimes : (j - i);
    }
    return (MaxTimes + 1);//因为是线段,所以要加1表示覆盖的点数
}
int main(void)
{
    int A[] = {-1, 0, 3, 9, 11, 13, 14, 25};
    int L = 5;
    int result = MaxTimesOfL(A, L);
    printf("\nthe max times is %d\n", result);
    return 0;
}


 

更新内容:(10月4日下午)

  有网友指出,我的算法其实没必要申请多余的数组,那么有没有更加高效的算法呢,我身边的一个大神给了我一个O(N)复杂度的算法:

  他的原话:两个指针,一个front,一个rear,每次front-rear,比L小,看覆盖的点数。保存覆盖点数的最大值,然后front++;比L大,rear++,每个数最多遍历2遍,复杂度O(N)。

  对于这个算法,他给了一个形象的比喻:

  就好像一条长度为L的蛇。头伸不过去的话,就把尾巴缩过来最多只需要走一次,就知道能覆盖几个点

实现代码:

  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. int main(void)  
  4. {  
  5.     int front = 0 , rear = 0;//设置首尾指针索引   
  6.     int cnt = 8;  
  7.     int L = 15;//绳子长度   
  8.     int MaxTimes = 0;  
  9.     int arr[] = {-1, 0, 3, 9, 11, 13, 14, 25};//数轴上的点   
  10.     while(front < cnt)  
  11.     {  
  12.         //比L小,则计算MaxTimes,作front++;   
  13.         if(arr[front] - arr[rear] <= L)  
  14.         {  
  15.             MaxTimes = MaxTimes > (front - rear) ? MaxTimes : (front - rear);  
  16.             front++;  
  17.         }  
  18.         else//比L大,rear++;   
  19.         {  
  20.             rear++;  
  21.         }  
  22.     }  
  23.     printf("the max times is %d\n", MaxTimes + 1);//第一个数是没有参与计数的,所以要在最后加1   
  24.     return 0;  
  25. }  
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    int front = 0 , rear = 0;//设置首尾指针索引
    int cnt = 8;
    int L = 15;//绳子长度
    int MaxTimes = 0;
    int arr[] = {-1, 0, 3, 9, 11, 13, 14, 25};//数轴上的点
    while(front < cnt)
    {
        //比L小,则计算MaxTimes,作front++;
        if(arr[front] - arr[rear] <= L)
        {
            MaxTimes = MaxTimes > (front - rear) ? MaxTimes : (front - rear);
            front++;
        }
        else//比L大,rear++;
        {
            rear++;
        }
    }
    printf("the max times is %d\n", MaxTimes + 1);//第一个数是没有参与计数的,所以要在最后加1
    return 0;
}



 

 

最后贴一下试题:


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值