在线编程习题

题目1:
一个整型数组,将其划分为和相同的4个切片,例如:{ 2, 3, 5, 1, 2, 2, 1, 1, 3 },切片操作后划分为:{2,3},{5},{1,2,2},{1,1,3},也就找到所谓的四等分点。只不过输出结果为true或者false(是否能得到这样的4个切片)。同时要求时间复杂度和空间复杂度为o(n)。

    public static boolean resolve(int[] a){
        int sum = 0;
        for(int i:a){
            sum += i;
        }
        int sliceSum = sum/4;
        if(sliceSum*4!=sum){
            return false;
        }
        int[] sliceIndex = new int[4];
        int sliceCount = 0;
        int tmpNum = 0;
        for(int i=0;i<a.length;i++){
            tmpNum += a[i];
            if(tmpNum == sliceSum){
                sliceIndex[sliceCount] = i;
                sliceCount++;
                tmpNum = 0;
            }
        }
        if(sliceIndex[3] == a.length-1){
            return true;
        }
        return false;
    }

题目2:
小猴子下山,沿着下山的路由一排桃树,每棵树都结了一些套子。小猴子想摘桃子,但是有一些条件需要遵守,小猴子只能沿着下山的方向走,不能回头,每棵树最多摘一个,而且一旦摘了一棵树的桃子,就不能再摘比这棵树结的桃子少的树上的桃子了,那么小猴子最多能摘几个桃子呢?举例说明,比如有5课树,分别结了10,4,5,12,8颗桃子,那么小猴子最多能摘3颗桃子,来自于结了4,5,8颗桃子的树。

public static int resolve(int[] a){
        int[] result = new int[a.length];
        for(int i=0;i<a.length;i++){
            result[i]=1;
            for (int j = 0; j < i; j++) {
                //如果是i位置大于j位置,并且j位置的最长递增子序列的长度+1长于目前i位置的最长递增子序列的长度,则更新i位置的最长递增子序列
                if (a[j] <= a[i] && result[j] + 1 > result[i]) {
                    result[i] = result[j] + 1;
                }
            }
        }
        int max = 1;
        for(int i : result){
            if(i>1){
                max = i;
            } 
        }
        return max;
    }

题目3:
一个淘宝的订单中包含n(10>=n>=1)种商品A1,A2,…,An,每种商品数量分别为a1,a2,…,an个,记做{a1,a2,…,an}(ak>0)。订单在仓库生产过程中,仓库为了提升作业效率,会提前对热门组合商品进行预包装。假设这n个商品有m(9>=m>=1)个商品组合,每个组合bomk包含A1,A2,…,An的数量分别为{b1,b2,…,bn}(bk>=0,至少存在一个bk>0)

举例如下:
订单包含A,B,C商品,数量为{2,3,1},商品组合bom1{2,1,1},bom2{1,1,0},bom3{0,1,1}

对以上订单匹配给定商品组合,得到的可能匹配结果为:res1.匹配到组合1一套,剩余B商品;res2.匹配到组合2两套,组合3一套,不剩商品;
现要求订单的最优匹配,最优匹配的原则为:1.匹配组合后,剩余商品种类数越少越好;2.在剩余商品种类数相同的情况下,匹配到的组合种类数越少越好;
例如上面例子,我们认为res2优于res1。

现需要编写程序,输入格式为:
n,m
a1,a2,…,an
bom1,b11,b12,…,b1n
bom2,b21,b22,…,b2n
….
bomm,bm1,bm2,…,bmn

输入数据的格式说明(数据间使用英文逗号分隔):
第一行数据:n个商品,m个预包方案
第二行数据:商品1个数,商品2个数,。。。,商品n个数
第三行数据:bom1,商品1个数,商品2个数,。。。,商品n个数
第n-1行数据:。。。。
第n行数据:bomn,商品1个数,商品2个数,。。。,商品n个数

针对输入数据找出最优匹配,输出最优匹配的组合及套数,比如针对上面的例子输出:
match result:
bom2*2,bom3*1
注:输出结果有多个时可以乱序

public class test {
    public static void main(String[] args) {
        List<Integer> order = new ArrayList<Integer>();
        Map<String, List<Integer>> boms = new HashMap<String, List<Integer>>();

        Scanner in = new Scanner(System.in);
        String line = in.nextLine();

        Integer n = Integer.parseInt(line.split(",")[0]);
        Integer m = Integer.parseInt(line.split(",")[1]);

        line = in.nextLine();
        String[] itemCnt = line.split(",");
        for(int i = 0; i < n ; i++){
            order.add(Integer.parseInt(itemCnt[i]));
        }

        for(int i = 0; i < m; i++){
            line = in.nextLine();
            String[] bomInput = line.split(",");
            List<Integer> bomDetail = new ArrayList<Integer>();

            for(int j = 1; j <= n; j++ ){
                bomDetail.add(Integer.parseInt(bomInput[j]));
            }
            boms.put(bomInput[0], bomDetail);
        }
        in.close();

        Map<String, Integer> res = resolve(order, boms);

        System.out.println("match result:");
        for(String key : res.keySet()){
            System.out.println(key+"*"+res.get(key));
        }
    }
    // write your code here
    public static Map<String, Integer> resolve(List<Integer> order, Map<String, List<Integer>> boms) {
        自己实现
    }
}

题目4:
小易有一个长度为N的正整数数列A = {A[1], A[2], A[3]…, A[N]}。
牛博士给小易出了一个难题:
对数列A进行重新排列,使数列A满足所有的A[i] * A[i + 1](1 ≤ i ≤ N - 1)都是4的倍数。
小易现在需要判断一个数列是否可以重排之后满足牛博士的要求。
输入描述:

输入的第一行为数列的个数t(1 ≤ t ≤ 10),
接下来每两行描述一个数列A,第一行为数列长度n(1 ≤ n ≤ 10^5)
第二行为n个正整数A[i](1 ≤ A[i] ≤ 10^9)

输出描述:

对于每个数列输出一行表示是否可以满足牛博士要求,如果可以输出Yes,否则输出No。
示例1
输入

2
3
1 10 100
4
1 2 3 4
输出

Yes
No
思路:
显然,任意数和 4 的倍数相乘,其结果仍是 4 的倍数;
显然,若存在任意数量 2 的倍数,两两之间乘起来就是 4 的倍数;
如果存在一个数不是 2 的倍数,即它是一个奇数:
放在 2 的倍数旁边,一定不符合要求;
放在 4 的倍数旁边,相乘结果仍是 4 的倍数。

因此符合要求的排列分两种情况:
存在 2 的倍数,所有 2 的倍数相邻排列,需要一个 4 的倍数连接剩下的数,奇数最多和 4 的倍数数量相等,要求 countMod4 >= countOdd
没有 2 的倍数,原本放 2 的倍数一端可以改放一个奇数,countMod4 >= countOdd - 1

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        String[] res = new String[n];
        for(int i=0;i<n;i++){
            int a = input.nextInt();
            int[] arr = new int[a];
            for(int j=0;j<arr.length;j++){
                arr[j] = input.nextInt();
            }
            res[i] = resolve(arr);
        }
        for(String s:res){
            System.out.println(s);
        }
    }
    public static String resolve(int[] a){
        int num_odd = 0;
        int num_2 = 0;
        int num_4 = 0;
        for(int i=0;i<a.length;i++){
            if(a[i]%2==0){
                if(a[i]%4==0){
                    num_4++;
                }else{
                    num_2++;
                }
            }else{
                num_odd++;
            }
        }
        if(num_2==0){
            if(num_4>=num_odd-1){
                return "Yes";
            }else{
                return "No";
            }
        }else{
            if(num_4>=num_odd){
                return "Yes";
            }else{
                return "No";
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/m0_37459945/article/details/79565033