手串——字节跳动2018校招大数据方向(第二批)

1.题目

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 64M,其他语言128M

作为一个手串艺人,有金主向你订购了一条包含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颗串珠是透明的。

2.思路

观察题目,本题可以做如下改变,即:对与每一种颜色,相邻两颗相同颜色的串珠之间包含这两颗的串珠数目如果小于等于m则不和要求,如果大于m则符合要求(ps:一定要注意他是个环状的结构所以不进要和前比也要和后比)。根据分析还是考虑使用hashmap,将串珠颜色作为k,创建一个长度为三的int数组作为value,int[0]负责存储第一个key颜色的串珠编号,int[1]负责存储当前最后一个key颜色的串珠编号,int[2]负责存储该key颜色是否符合要求,符合为0,不符合为1(ps:因为我们主要关注key是否符合要求所以串珠编号没有必要都存起来)。按顺序对输入数据进行遍历存储,每次存储时对比int[1]存储的上次该颜色串珠编号和当前正在进行存入操作的串珠编号,当前正在进行存入操作的串珠编号和int[0]存储的该颜色初始编号,通过对比确定颜色是否符合要求然后写入int[2]中。最后通过key遍历value,然后根据int[2]中存储数据,判定不符合要求的颜色并将种数进行累加,即完成题目要求

3.实现代码

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int c = sc.nextInt();
        Map<Integer,int[]> map = new HashMap<Integer,int[]>();
        for(int i=0;i<n;i++ ){
            int nu = sc.nextInt();
            for(int j=0;j<nu;j++){
                int co = sc.nextInt();
                int[] arr = new int[3];
                if(!map.containsKey(co)){
                    arr[0]= i+1;
                    map.put(co,arr);
                }
                else{
                    arr = map.get(co);
                    int range = (i+2)- arr[1];
                    int cy = n-i+ arr[0];
                    //System.out.println(range+" "+cy+" "+m+" "+arr[1]);
                    if(arr[1] == 0 || range > m){
                        arr[1] = i+1;
                        map.put(co, arr);
                    }
                    if(range<=m || cy<=m){
                        arr[1] = i+1;
                        arr[2] =1;
                        map.put(co, arr);
                    }
 
                }
            }
 
        }
        int count = 0;
 
        for (Map.Entry<Integer, int[]> entry:map.entrySet()) {
 
            int [] lastarr = new int [3];
            lastarr = entry.getValue();
            //System.out.println(lastarr[1]);
            if(lastarr[2]==1){
                count = count+1;
            }
        }
        System.out.print(count);
 
    }
}

4.实际提交结果

在这里插入图片描述

5.经验教训

还是在于两个串珠的编号和两个串珠及其中间串珠的数量的关系的一些+1,-1弄得有些混乱,头疼,我可能是个傻子。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值