hdu4749
来源:互联网 发布:aa录音软件官方下载 编辑:程序博客网 时间:2024/06/04 23:18
题意来自
题目大意:学校要举办一场典礼,要从n个学生中选若干支队伍来,每支队伍有m个人。然后现在将学生的身高划分成k个等级,接着按照学生的顺序给出学生的身高等级,再然后,给出m个人的队伍要求的相对高度。然后要求从n个中间挑选连续的m个人,满足相对高度即可组成一支队伍。问说最多可以组成多少支队伍。
解题思路:KMP算法的变形,只不过在判断相等的时候有点难办,因为它算的是相对高度,就是同一支队伍中,对应比自己高的个数,相等的个数,比自己矮的个数都要和要求的相等,所以要开一个cx,cy数组,将KMP中判断相等写成一个函数。
import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.io.StreamTokenizer;import java.math.BigInteger;import java.text.DecimalFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.NavigableSet;import java.util.PriorityQueue;import java.util.Queue;import java.util.Scanner;import java.util.Set;import java.util.SortedSet;import java.util.Stack;import java.util.StringTokenizer;import java.util.TreeSet;public class Main { public static void main(String[] args) throws IOException{ StreamTokenizer cin = new StreamTokenizer(new BufferedInputStream(System.in)) ; InputReader in = new InputReader(System.in) ; PrintWriter out = new PrintWriter(System.out) ; while(cin.nextToken() != cin.TT_EOF){ int n = (int) cin.nval ; cin.nextToken() ; int m = (int) cin.nval ; cin.nextToken() ; int k = (int) cin.nval ; new Task().solve(cin , n , m , k , out); //out.flush() ; } out.flush() ; }}class Task{ static final int maxn = 100008 ; static int[] Next = new int[maxn] ; static int[] a = new int[maxn] ; static int[] b = new int[maxn] ; static int[][] sa = new int[maxn][26] ; static int[][] sb = new int[maxn][26] ; int n , m , k ; boolean ok1(int i , int j){ int l1 , l2 , e1 , e2 ; l1 = l2 = e1 = e2 = 0 ; for(int t = 1 ; t <= k ; t++){ if(t < b[i]) l1 += sb[i][t] - sb[i-j][t] ; else if(t == b[i]) e1 += sb[i][t] - sb[i-j][t] ; if(t < b[j]) l2 += sb[j][t] ; else if(t == b[i]) e2 += sb[j][t] ; } return l1==l2 && e1==e2 ; } boolean ok2(int i , int j){ int l1 , l2 , e1 , e2 ; l1 = l2 = e1 = e2 = 0 ; for(int t = 1 ; t <= k ; t++){ if(t < a[i]) l1 += sa[i][t] - sa[i-j][t] ; else if(t == a[i]) e1 += sa[i][t] - sa[i-j][t] ; if(t < b[j]) l2 += sb[j][t] ; else if(t == b[j]) e2 += sb[j][t] ; } return l1==l2 && e1==e2 ; } void getNext(){ int i,j; j=0; Next[1]=0; for(i=2;i<=m;i++){ while(j>0 && !ok1(i , j+1)) j=Next[j]; if(ok1(i , j+1)) j++; Next[i]=j; } } int kmp(){ int i,j; int cnt=0; j=0; // 初始状态为 0 for(i=1;i<=n;i++){ while(j>0 && !ok2(i,j+1)) j=Next[j]; if(ok2(i , j+1)) j++; if(j == m){ cnt++; j = 0 ; //特殊处理一下 } } return cnt; } void solve(StreamTokenizer cin , int n , int m , int k , PrintWriter out) throws IOException{ this.n = n ; this.m = m ; this.k = k ; for(int i = 0 ; i <= n ; i++) Arrays.fill(sa[i] , 0) ; for(int i = 0 ; i <= n ; i++) Arrays.fill(sb[i] , 0) ; for(int i = 1 ; i <= n ; i++){ cin.nextToken() ; a[i] = (int)cin.nval ; for(int j = 1 ; j <= k ; j++) sa[i][j] = sa[i-1][j] ; sa[i][a[i]]++ ; } for(int i = 1 ; i <= m ; i++){ cin.nextToken() ; b[i] = (int)cin.nval ; for(int j = 1 ; j <= k ; j++) sb[i][j] = sb[i-1][j] ; sb[i][b[i]]++ ; } getNext() ; out.println(kmp()) ; }} class InputReader{ public BufferedReader reader ; public StringTokenizer tokenizer ; public InputReader(InputStream stream){ reader = new BufferedReader(new InputStreamReader(stream), 32768) ; tokenizer = null ; } public String next(){ while(tokenizer == null || ! tokenizer.hasMoreTokens()){ try{ tokenizer = new StringTokenizer(reader.readLine()); }catch (IOException e) { throw new RuntimeException(e); } } return tokenizer.nextToken(); } public int nextInt(){ return Integer.parseInt(next()); } public long nextLong(){ return Long.parseLong(next()); } public double nextDouble(){ return Double.parseDouble(next()); }}
0 0