[SCOI2009]生日禮物
阿新 • • 發佈:2022-02-11
小西有一條很長的綵帶,綵帶上掛著各式各樣的彩珠。已知彩珠有N個,分為K種。簡單的說,可以將綵帶考慮為x軸,每一個彩珠有一個對應的座標(即位置)。某些座標上可以沒有彩珠,但多個彩珠也可以出現在同一個位置上。 小布生日快到了,於是小西打算剪一段綵帶送給小布。為了讓禮物綵帶足夠漂亮,小西希望這一段綵帶中能包含所有種類的彩珠。同時,為了方便,小西希望這段綵帶儘可能短,你能幫助小西計算這個最短的長度麼?綵帶的長度即為綵帶開始位置到結束位置的位置差。
輸入描述:
第一行包含兩個整數N, K,分別表示彩珠的總數以及種類數。 接下來K行,每行第一個數為Ti,表示第i種彩珠的數目。接下來按升序給出Ti個非負整數,為這Ti個彩珠分別出現的位置。
輸出描述:
應包含一行,為最短綵帶長度。
分析
這題類似於字串,如果將座標軸視為綵帶,可以採用尺取法找出這段最優綵帶,但是綵帶的長度達到了2的31次方!而且同一個位置上可能有多種彩珠,因此這個座標軸不能直接作為陣列。應該離散化,使用結構體node記錄彩珠的種類kind和位置pos,陣列存放node,並根據pos進行排序,對這個陣列進行尺取法。
AC
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Comparator; import java.util.Arrays; public class Main { public static class Node { int pos; int kind; Node(int kind, int pos) { this.kind = kind; this.pos = pos; } } public static class MyCompare implements Comparator<Node> { public int compare(Node o1, Node o2) { return o1.pos - o2.pos; } } static int[] hash; static int K; public static boolean check() { for(int i = 0; i < K; ++i) { if(hash[i] == 0) return false; } return true; } public static void main(String[] args) throws IOException { BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); String[] strs = bf.readLine().split(" "); int N = Integer.parseInt(strs[0]); K = Integer.parseInt(strs[1]); int min = Integer.MAX_VALUE; Node[] nodes = new Node[N]; hash = new int[K]; for(int i = 0, n = 0; i < K; ++i) { strs = bf.readLine().split(" "); for(int j = 1; j < strs.length; ++j) { nodes[n++] = new Node(i, Integer.parseInt(strs[j])); } } Arrays.sort(nodes, new MyCompare()); int i = 0, j = 0; while(i < N && j < N) { ++hash[nodes[j].kind]; while(i < N && check()) { min = Math.min(min, nodes[j].pos - nodes[i].pos); --hash[nodes[i++].kind]; } ++j; } System.out.println(min); } }
連結:https://ac.nowcoder.com/acm/contest/20960/1031
來源:牛客網
本文來自部落格園,作者:brbrbr,轉載請註明原文連結:https://www.cnblogs.com/brbrbr/p/15884565.html