刷刷笔试题~(4)编程

来源:互联网 发布:mac运行速度变慢 编辑:程序博客网 时间:2024/05/21 09:54

1.[编程题]左右最值最大差

给定一个长度为N(N>1)的整型数组A,可以将A划分成左右两个部分,左部分A[0..K],右部分A[K+1..N-1],K可以取值的范围是[0,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少?
给定整数数组A和数组的大小n,请返回题目所求的答案。
测试样例:
[2,7,3,1,1],5
返回:6

import java.util.*;public class MaxGap {    public int findMaxGap(int[] A, int n) {        // write code here        int max=-1;        int min;        for(int i=0;i<n;i++){            if(A[i]>max){                max=A[i];            }        }        min=A[0]>A[n-1]?A[n-1]:A[0];        return max-min;    }}


这个题还有些问题


2.[编程题]出专辑

你作为一名出道的歌手终于要出自己的第一份专辑了,你计划收录 n 首歌而且每首歌的长度都是 s 秒,每首歌必须完整地收录于一张 CD 当中。

每张 CD 的容量长度都是 L 秒,而且你至少得保证同一张 CD 内相邻两首歌中间至少要隔 1 秒。

为了辟邪,你决定任意一张 CD 内的歌数不能被 13 这个数字整除,那么请问你出这张专辑至少需要多少张 CD ?

输入描述:

每组测试用例仅包含一组数据,每组数据第一行为三个正整数 n, s, L。 保证 n ≤ 100 , s ≤ L ≤ 10000 

输出描述:

输出一个整数代表你至少需要的 CD 数量。

输入例子:

7 2 6

输出例子:

4



import java.util.Scanner;public class Main{    public static void main(String[] args){        Scanner sc=new Scanner(System.in);        int n=sc.nextInt();        int s=sc.nextInt();        int L=sc.nextInt();        int cd=0;//需要的CD数        int cd_s=(L+1)/(s+1);//每张CD可以放的歌曲数        if(cd_s>n){//CD可以放的歌曲数大于总共的歌曲数            if(n%13==0)//歌曲数是13的倍数,不能只放在一张CD中                {cd=2;}            else                {cd=1;}        }        else{//总共的歌曲数大于每张CD可以放的歌曲数            if(cd_s%13==0)//每张CD可以放的歌曲数是13的倍数                cd_s--;//将每张CD可以放的歌曲数减1            if(n%cd_s==0)//总歌曲数刚好是每张CD可以放的歌曲数的整数倍                cd=n/cd_s;            if(n%cd_s!=0){//不能整存时                if((n%cd_s)%13==0){//多出来的零头是13的倍数                    if((cd_s-1)%13==0&&(cd_s-n%cd_s)==1)//从放满的CD中拿出来一个后,原来放满的CD变成13的倍数,而且零头那边只剩了一个位置                        cd=n/cd_s+2;                    else                        cd=n/cd_s+1;//可以从放满的CD中拿出来一个,让零头不是13的倍数,这样就不用多加一张CD了                                        }else                    cd=n/cd_s+1;            }                                    }        System.out.println(cd);    }}
这道题很简单,但是要考虑的情况很多,测试用例总是不能完全通过。


3.[编程题]字符混编
A、B和C。如果C包含且仅包含来自A和B的所有字符,而且在C中属于A的字符之间保持原来在A中的顺序,属于B的字符之间保持原来在B中的顺序,那么称C是A和B的混编。实现一个函数,判断C是否是A和B的混编。
给定三个字符串A,B和C,及他们的长度。请返回一个bool值,代表C是否是A和B的混编。保证三个串的长度均小于等于100。


测试样例:
"ABC",3,"12C",3,"A12BCC",6
返回:true


解题思路:

把这道题转换成最长公共子序列的问题。

因为“C包含且仅包含来自A和B的所有字符”,也就是说C中有所有A、B的字符,分别求出AC、BC的最长公共子序列应该分别等于A、B的长度,且相加后为C的长度

import java.util.*;import java.util.Scanner;public class Mixture {    public boolean chkMixture(String A, int n, String B, int m, String C, int v) {        // write code here        int x=LCS(A,C);        int y=LCS(B,C);        if(x==n&&y==m&&x+y==v){            return true;        }else            return false;    }    public static int LCS(String x,String y){        int m=x.length();        int n=y.length();        int dp[][]=new int[m+1][n+1];        for(int i=0;i<=m;i++){            dp[i][0]=0;        }        for(int j=0;j<=n;j++){            dp[0][j]=0;        }        for(int j=1;j<=n;j++){            for(int i=1;i<=m;i++){                if(x.charAt(i-1)==y.charAt(j-1)){                    dp[i][j]=dp[i-1][j-1]+1;                }else{                    dp[i][j]=(dp[i][j-1]>=dp[i-1][j]?dp[i][j-1]:dp[i-1][j]);                }            }        }        return dp[m][n];    }    }




4.[编程题]跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。


对于本题,前提只有 一次 1阶或者2阶的跳法。

a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);

b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)

c.由a\b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2) 

d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2

e.可以发现最终得出的是一个斐波那契数列:

        

              | 1, (n=1)

f(n) =     | 2, (n=2)

              | f(n-1)+f(n-2) ,(n>2,n为整数)

public class Solution {    public int JumpFloor(int target) {        if(target==1||target==2){            return target;        }else if(target<1){return -1;}        else{            return JumpFloor(target-1)+JumpFloor(target-2);        }    }}


但是能用迭代就不要用递归哦


public class Solution {    public int JumpFloor(int target) {        if(target==1||target==2){            return target;        }        int jumpNum=0;//跳法        int numMinusOne=2;//台阶数减1的跳法        int numMinusTwo=1;//台阶数减2的跳法        for(int i=3;i<=target;i++){            jumpNum=numMinusOne+numMinusTwo;            numMinusTwo=numMinusOne;            numMinusOne=jumpNum;        }        return jumpNum;    }}


5.[编程题]变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。

求该青蛙跳上一个n级的台阶总共有多少种跳法。


解题思路:

把这道题当成算数题来看,可以找到规律,每多一层台阶的跳法是前一层台阶跳法的2倍


public class Solution {    public int JumpFloorII(int target) {        if(target==1||target==2){            return target;        }else if(target<1){return -1;}        else{            return JumpFloorII(target-1)*2;        }            }}

显然好像有比这个更好的解决办法:

位移操作~,,来来让我们看看吧!


>>右移操作
x>>y
就是x除以2的y次方,取整数

<<左移操作
X<<y
就是x乘以2的y次方



通过算数的方法可以求出  跳法数量为2^(n-1)


public class Solution {    public int JumpFloorII(int target) {        int a=1;        return a<<(target-1);    }}



6.[编程题]矩形覆盖

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?


依旧是斐波那契数列
2*n的大矩形,和n个2*1的小矩形
其中target*2为大矩阵的大小
有以下几种情形:
1、target = 1大矩形为2*1,只有一种摆放方法,return1;
2、target = 2 大矩形为2*2,有两种摆放方法,return2;
3、target = n 分为两步考虑:

如果第一格竖着放,只占一个格,还剩n-1格  f(target-1)种方法

如果前两格横着放两个,占两个格,还剩n-2格  f(target-2)种方法


public class Solution {    public int RectCover(int target) {        if(target==0||target==1||target==2){            return target;        }else if(target<0){return -1;}        else{            return RectCover(target-1)+RectCover(target-2);        }    }}









0 0
原创粉丝点击