列表

详情


NC54751. String Compression

描述

Bob最近沉迷于字符串压缩算法,给定一个字符串S将其压缩成若干形如( l , c )的对,其中 l 表示当前压缩串中该字符 c 连续出现的长度。

例如字符串 "abbbcd" 可被压缩成 {(1,a) ,(3,b) ,(1,c) ,(1,d) }、{(1,a) ,(1,b) ,(2,b) ,(1,c) ,(1,d) } 、{(1,a) ,(1,b) ,(1,b),(1,b) ,(1,c) ,(1,d) }。

现给出两个字符串S , T 的压缩后的形式,请问在解压后T在S作为子串的出现次数。

,,c为小写拉丁字母。

输入描述

第一行输入两个整数n和m,分别表示S和T压缩后的对数。

第二行输入n个形如 l c 的压缩对,表示S压缩后的形式。

第三行输入m个形如 l c 的压缩对,表示T压缩后的形式。

输出描述

输出一个整数表示解压后T作为子串出现在S中的出现次数。

示例1

输入:

2 1
2 a 1 a
1 a

输出:

3

说明:

2 a需要注意scanf("%d %c",&a,&b)读入(即:注意中间空格)

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Java(javac 1.8) 解法, 执行用时: 393ms, 内存消耗: 42952K, 提交时间: 2019-12-07 23:44:43

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader sc = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, sc, out);
        out.close();
    }

    static class Task {
    	public int[] getNext(Node[] p,int len) {
    		int[] next=new int[len+10];
    	
    		int i=0;
    		int j=-1;
    		next[i]=-1;
    		while(i<len) {         //构造next数组
    			if(j==-1||(p[i].c==p[j].c&&p[i].cnt==p[j].cnt))               
    				next[++i]=++j;
    			else
    				j=next[j];
    		}
    		
    		return next;
    	}
    	
    	public long KMP(Node[] x,int m,Node[] y,int n,Node[] nowS,int cntS) {   //x是模式串  y是主串
    		int i,j;
    		long ans=0;
    		i=j=0;
    		int[] next=getNext(x,m);
    		while(i<n){
    	    	while(j!=-1 && (y[i].c!=x[j].c||y[i].cnt!=x[j].cnt))
    		    	j=next[j];
    		    i++;
    		    j++;
    		    if(j>=m){
    	    	   int index=i-m-1;
    	    	   if(index>=0&&i<n) {
    	    		   if(y[index].c==nowS[0].c&&y[index].cnt>=nowS[0].cnt&&y[i].c==nowS[cntS-1].c&&y[i].cnt>=nowS[cntS-1].cnt)
    	    			   ans++;
    	    	   }
    	    	   j=next[j];
    		    }
    	    }
    		return ans;
    	}
    	
        public void solve(int testNumber, InputReader sx, PrintWriter outs) throws IOException {
        /*	File file_in=new File("C:\\Users\\Garett\\Desktop\\题目\\String Compression\\数据","16.in");
    	    FileReader in=new FileReader(file_in);
    	    BufferedReader sc=new BufferedReader(in);
    	    File file_out=new File("C:\\Users\\Garett\\Desktop\\题目\\String Compression\\数据","16.out");
    		FileWriter out=new FileWriter(file_out);
    		BufferedWriter puts=new BufferedWriter(out);
    	    
    	    String[] temp=sc.readLine().split(" ");
            int n=Integer.parseInt(temp[0]);
            int m=Integer.parseInt(temp[1]);*/
        	int n=sx.nextInt();
        	int m=sx.nextInt();
        	Node[] t=new Node[n];
        	Node[] s=new Node[m];
        	int cnt=0;
        /*	temp=sc.readLine().split(" ");
        	for(int i=0;i<2*n;i+=2) {
        		long l=Long.parseLong(temp[i]);
        		char c=temp[i+1].charAt(0);
        	//	System.out.println(l+" "+c);
        		t[cnt++]=new Node(c,l);
        	}
        	cnt=0;
        //	System.out.println();
        	temp=sc.readLine().split(" ");
        	for(int i=0;i<2*m;i+=2) {
        		long l=Long.parseLong(temp[i]);
        		char c=temp[i+1].charAt(0);
        		//System.out.println(l+" "+c);
        		s[cnt++]=new Node(c,l);
        	}*/
        	for(int i=0;i<n;i++) {
        		long l=sx.nextLong();
        		char c=sx.next().charAt(0);
        	//	System.out.println(l+" "+c);
        		t[cnt++]=new Node(c,l);
        	}
        	cnt=0;
        //	System.out.println();
       // 	temp=sc.readLine().split(" ");
        	for(int i=0;i<m;i++) {
        		long l=sx.nextLong();
        		char c=sx.next().charAt(0);
        		//System.out.println(l+" "+c);
        		s[cnt++]=new Node(c,l);
        	}
        	Node[] nowT=new Node[n];
        	Node[] nowS=new Node[m];
        	int cntT=0;
        	int cntS=0;
        	nowT[cntT++]=t[0];
        	nowS[cntS++]=s[0];
        	for(int i=1;i<n;i++) {
        		if(t[i].c==nowT[cntT-1].c) 
        			nowT[cntT-1].cnt+=t[i].cnt;
        		else
        			nowT[cntT++]=t[i];
        	}
        	for(int i=1;i<m;i++) {
        		if(s[i].c==nowS[cntS-1].c) 
        			nowS[cntS-1].cnt+=s[i].cnt;
        		else
        			nowS[cntS++]=s[i];
        	}
            if(cntS==1) {
            	long ans=0;
            	for(int i=0;i<cntT;i++) {
            		if(nowT[i].c==nowS[0].c&&nowT[i].cnt>=nowS[0].cnt) {
            			ans+=nowT[i].cnt-nowS[0].cnt+1;
            		}
            	}
            /*	puts.write(ans+"");
            	puts.newLine();
            	puts.close();
            	sc.close();*/
            	outs.println(ans);
            	return ;
            }
            if(cntS==2) {
            	long ans=0;
            	for(int i=0;i<cntT-1;i++) {
            		if(nowT[i].c==nowS[0].c&&nowT[i+1].c==nowS[1].c&&nowT[i].cnt>=nowS[0].cnt&&nowT[i+1].cnt>=nowS[1].cnt)
            			ans++;
            	}
            	outs.println(ans);
            /*	puts.write(ans+"");
            	puts.newLine();
            	puts.close();
            	sc.close();*/
            	return ;
            }
            Node[] bufS=new Node[cntS];
            int nowCntS=0;
            for(int i=1;i<cntS-1;i++)
            	bufS[nowCntS++]=nowS[i];
            outs.println(KMP(bufS,nowCntS,nowT,cntT,nowS,cntS));
          /*  puts.write(KMP(bufS,nowCntS,nowT,cntT,nowS,cntS)+"");
        	puts.newLine();
        	puts.close();
        	sc.close();*/
        }
    }
    
    static class Node{
    	char c;
    	long cnt;
    	
    	public Node(char c,long cnt) {
    		this.c=c;
    		this.cnt=cnt;
    	}
    }

    static class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
        
        public double nextDouble() throws NumberFormatException, IOException {
        	return Double.parseDouble(next());
        }
        
        public BigInteger nextBigInteger() throws IOException {
        	return new BigInteger(next());
        }
    }
}

C++11(clang++ 3.9) 解法, 执行用时: 64ms, 内存消耗: 10296K, 提交时间: 2019-12-07 23:46:10

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e6+7;
struct node{
	ll x;
	char val;
};
vector<node> s,t;
ll nextt[N],extend[N];
void getnext(vector<node> s){
    ll po; ll len=s.size();
    nextt[0]=len;
    ll pos=0;
    while(pos<len-1&&s[pos].x==s[pos+1].x&&s[pos].val==s[pos].val) pos++; 
    nextt[1]=pos;
    po=1;
    for(ll i=2;i<len;i++){
        if(nextt[i-po]+i<po+nextt[po])
            nextt[i]=nextt[i-po];
        else{
            ll j=po+nextt[po]-i;
            if(j<0) j=0;
            while(i+j<len&&s[j].x==s[i+j].x&&s[j].val==s[i+j].val) j++;
            nextt[i]=j;
            po=i;
        }
    }
}
void exkmp(vector<node> a,vector<node> b){
    ll len1=a.size(); ll len2=b.size();
    getnext(a);
    ll po; ll pos=0;
    while(pos<len1&&pos<len2&&a[pos].x==b[pos].x&&a[pos].val==b[pos].val) pos++;
    extend[0]=pos;
    po=0;
    for(ll i=1;i<len2;i++){
        if(nextt[i-po]+i<extend[po]+po)
            extend[i]=nextt[i-po];
        else{
            ll j=po+extend[po]-i;
            if(j<0) j=0;
            while(i+j<len2&&j<len1&&a[j].x==b[i+j].x&&a[j].val==b[i+j].val) j++;
            extend[i]=j;
            po=i;
        }
    }
}
int main(){
	ll n,m; scanf("%lld%lld",&n,&m);
	ll lastx=0; char lastc=' ';
	for(ll i=1;i<=n;i++){
		ll x; char va;
		scanf("%lld %c",&x,&va);
		if(va==lastc) s[(ll)(s.size()-1)].x+=x;
		else s.push_back(node{x,va});
		lastc=va;
	}
	lastx=0; lastc=' ';
	for(ll i=1;i<=m;i++){
		ll x; char va;
		scanf("%lld %c",&x,&va);
		if(va==lastc) t[(ll)(t.size()-1)].x+=x;
		else t.push_back(node{x,va});
		lastc=va;
	}
	ll ans=0;
	if(t.size()==1){
		for(ll i=0;i<s.size();i++){
			if(s[i].val==t[0].val)
			ans+=max(0ll,s[i].x-t[0].x+1);
		}
		printf("%lld\n",ans);
		return 0;
	}
	vector<node> tmp;
	for(ll i=0;i<t.size();i++){
		if(i==0||i==t.size()-1) continue;
		tmp.push_back(t[i]);
	}
	exkmp(tmp,s);
	ll len=s.size(),val=tmp.size();
	for(ll i=1;i<len;i++){
		if(extend[i]==val&&t[0].x<=s[i-1].x&&t[0].val==s[i-1].val&&t[(ll)(t.size()-1)].x<=s[i+extend[i]].x
		&&t[(ll)(t.size()-1)].val==s[i+extend[i]].val) ans++;
	}
	printf("%lld\n",ans);
}

上一题