关闭

刷刷笔试题~(4)编程

285人阅读 评论(0) 收藏 举报
分类:

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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:52321次
    • 积分:1546
    • 等级:
    • 排名:千里之外
    • 原创:98篇
    • 转载:52篇
    • 译文:0篇
    • 评论:12条
    最新评论