编程题(内存条匹配、用户喜好值计算、手串颜色不重复)---- 2018.08.02

package m08d02;

import java.util.Arrays;

/**
 * @author JackarooZhang
 * @date 2018/8/2 8:35
 */

/**
 * 给电脑装内存有一批没有安装内存的电脑需要安装内存,由于每台电脑运行的程序不同,必须安装大于等于最小内存需求的内存条才能让电脑正常工作。
 * 现有一批不同容量的内存条。用数组computers表示每天电脑对内存的最小需求量,例如[1,2,3]
 * 用数组memory表示每个内存条的规格,例如[1,1,2,3]
 * 计算能够正确安装内存的电脑台数?
 * 注:1. 内存需求了和内存条规格都是正整数 2. 每台电脑只能装一根内存条
 */
public class Item01 {

    public static void main(String[] args) {
        int[] computers = new int[] {4, 2, 8, 1, 2};
        int[] memory    = new int[] {16, 4, 2, 3};
        int rs = makeUpComputer(computers, memory);
        System.out.println(rs);
    }

    public static int makeUpComputer(int[] computers, int[] memory) {
        Arrays.sort(computers);
        Arrays.sort(memory);
        int index = 0;
        int count = 0;
        for (int i = 0; i < computers.length; i++) {
            // i:当前考察的电脑索引
            for (int j = index; j < memory.length; j++) {
                // j:当前内存条索引
                if (memory[j] >= computers[i]) {
                    index = j+1;
                    count++;
                    break;
                }
            }

        }

        return count;
    }

}
package m08d02;

import java.util.*;

/**
 * @author JackarooZhang
 * @date 2018/8/2 16:40
 */

/**
 * 为了不断优化推荐效果,今日头条每天要存储和处理海量数据。
 * 假设有这样一种场景:我们对用户按照它们的注册时间先后来标号,对于一类文章,每个用户都有不同的喜好值,
 * 我们会想知道某一段时间内注册的用户(标号相连的一批用户)中,有多少用户对这类文章喜好值为k。
 * 因为一些特殊的原因,不会出现一个查询的用户区间完全覆盖另一个查询的用户区间(不存在L1<=L2<=R2<=R1)。
 *
 * 输入示例:
 * 5
 * 1 2 3 3 5
 * 3
 * 1 2 1
 * 2 4 5
 * 3 5 3
 * 输出示例:
 * 1
 * 0
 * 2
 * 样例解释:
 * 有5个用户,喜好值为分别为1、2、3、3、5,
 * 第一组询问对于标号[1,2]的用户喜好值为1的用户的个数是1
 * 第二组询问对于标号[2,4]的用户喜好值为5的用户的个数是0
 * 第三组询问对于标号[3,5]的用户喜好值为3的用户的个数是2
 */
public class Item02 {

    public static void main(String[] args) {
        Queue<Integer> qr = solution();
        qr.stream().forEach(e -> System.out.println(e));
    }

    public static Queue<Integer> solution() {
        /* 第一行:用户数目 */
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        // 数组索引为用户编号(从1开始),值为用户喜好值
        int[] like = new int[n+1];

        /* 第二行:喜好值列表*/
        for (int i = 1; i <= n; i++) {
            like[i] = sc.nextInt();
        }

        Map<Integer, List<Integer>> map = new HashMap<>();
        for (int i = 1; i <= n; i++) {
            if (map.containsKey(like[i])) {
                map.get(like[i]).add(i);
            } else {
                List<Integer> users = new LinkedList<>();
                users.add(i);
                map.put(like[i], users);
            }
        }

        /* 第三行:查询组数 */
        int q = sc.nextInt();

        Queue<Integer> queryResult = new LinkedList<>();
        /* 其余行:查询内容(l, r, k)*/
        for (int i = 0; i < q; i++) {
            int l = sc.nextInt();
            int r = sc.nextInt();
            int k = sc.nextInt();
            int count = 0;
            if (map.containsKey(k)) {
                for (Integer index : map.get(k)) {
                    if (index >= l && index <= r) count++;
                }
            }
            queryResult.add(count);
        }

        return queryResult;
    }

}
package m08d02;

import java.util.*;

/**
 * @author JackarooZhang
 * @date 2018/8/2 17:12
 */

/**
 * 作为一个手串艺人,有金主向你订购了一条包含n个杂色串珠的手串——每个串珠要么无色,要么涂了若干种颜色。
 * 为了使手串的色彩看起来不那么单调,金主要求,手串上的任意一种颜色(不包含无色),
 * 在任意连续的m个串珠里至多出现一次(注意这里手串是一个环形)。
 * 手串上的颜色一共有c种。现在按顺时针序告诉你n个串珠的手串上,每个串珠用所包含的颜色分别有哪些。
 * 请你判断该手串上有多少种颜色不符合要求。即询问有多少种颜色在任意连续m个串珠中出现了至少两次。
 *
 * 输入描述:
 * 第一行输入n,m,c三个数,用空格隔开。(1 <= n <= 10000, 1 <= m <= 1000, 1 <= c <= 50)
 * 接下来n行每行的第一个数num_i(0 <= num_i <= c)表示第i颗珠子有多少种颜色。
 * 接下来依次读入num_i个数字,每个数字x表示第i颗柱子上包含第x种颜色(1 <= x <= c)
 *
 * 输入例子1:
 * 5 2 3
 * 3 1 2 3
 * 0
 * 2 2 3
 * 1 2
 * 1 3
 *
 * 输出例子1:
 * 2
 *
 * 例子说明1:
 * 第一种颜色出现在第1颗串珠,与规则无冲突。
 * 第二种颜色分别出现在第 1,3,4颗串珠,第3颗与第4颗串珠相邻,所以不合要求。
 * 第三种颜色分别出现在第1,3,5颗串珠,第5颗串珠的下一个是第1颗,所以不合要求。
 * 总计有2种颜色的分布是有问题的。
 * 这里第2颗串珠是透明的。
 */
public class Item03 {

    private static boolean IsVaild(ArrayList<Integer> a, int m, int n){
        if(a.size() == 0){
            return true;
        }
        boolean flag = true;
        for (int i = 0; i < a.size() - 1; ++i){
            if((a.get(i+1) - a.get(i)) < m){
                flag = false;
                break;
            }
        }
        int mLast = a.get(0) - (a.get(a.size() - 1) - n);
        if(mLast < m){
            flag = false;
        }
        return flag;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt(); // 串珠个数
        int m = scanner.nextInt(); // 间隔
        int c = scanner.nextInt(); // 颜色种数
        int[][] clist = new int[n][];
        for(int i = 0; i < n ;++i){
            int cNumber = scanner.nextInt();
            clist[i] = new int[cNumber];
            for (int j = 0; j < cNumber; ++ j){
                clist[i][j] = scanner.nextInt();
            }
        }
        int count = 0;
        for (int i = 0; i <= c; i++){
            ArrayList<Integer> temp = new ArrayList<Integer>();
            for(int j =0 ;j < n; ++j){
                for(int k = 0; k<clist[j].length; ++k){
                    if(clist[j][k] == i){
                        temp.add(j);
                    }
                }
            }
            if(!IsVaild(temp, m, n)){
                count++;
            }
        }
        System.out.println(count);
    }

    /*------------我的解答(错误)---------------*/
    public static void main2(String[] args) {
        int rs = solution();
        System.out.println(rs);
    }

    public static int solution() {
        Scanner sc = new Scanner(System.in);
        /* 第一行:珠子数、连续数、颜色种数 */
        int n = sc.nextInt();
        int m = sc.nextInt();
        int c = sc.nextInt();

        Map<Integer, List<Integer>> map = new HashMap<>();
        /* 其余行:第i个珠子中颜色种数、颜色值 */
        for (int i = 1; i < n+1; i++) {
            int cn = sc.nextInt();
            if (cn == 0) {
                int k = 0;
                int v = i;
                if (map.containsKey(k)) {
                    map.get(k).add(v);
                } else {
                    List<Integer> list = new ArrayList<>();
                    list.add(v);
                    map.put(k, list);
                }
            } else {
                for (int j = 0; j < cn; j++) {
                    int k = sc.nextInt();
                    int v = i;
                    if (map.containsKey(k)) {
                        map.get(k).add(v);
                    } else {
                        List<Integer> list = new ArrayList<>();
                        list.add(v);
                        map.put(k, list);
                    }
                }
            }
        }
        // 分析每种颜色在珠子上的分布是否符合条件
        int error = 0;
        for (Integer k : map.keySet()) {
            List<Integer> list = map.get(k);
            if (list.size() <= 1) continue;
            Integer first = list.get(0);
            Integer last = list.get(list.size()-1);
            if ((first-1 + n-last + 2) <= m) {
                error++;
                continue;
            }
            for (int i = 1; i < list.size(); i++) {
                if ( (list.get(i-1) + m) > list.get(i) ) {
                    error++;
                    continue;
                }
            }
        }

        return error;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值