zoukankan      html  css  js  c++  java
  • [USACO 2011 Dec Gold] Threatening Letter【后缀】

    Problem 3: Threatening Letter [J. Kuipers, 2002]
    
    FJ has had a terrible fight with his neighbor and wants to send him
    a nasty letter, but wants to remain anonymous. As so many before
    him have done, he plans to cut out printed letters and paste them
    onto a sheet of paper. He has an infinite number of the most recent
    issue of the Moo York Times that has N (1 <= N <= 50,000) uppercase
    letters laid out in a long string (though read in as a series of
    shorter strings). Likewise, he has a message he'd like to compose
    that is a single long string of letters but that is read in as a
    set of shorter strings.
    
    Being lazy, he wants to make the smallest possible number of cuts.
    FJ has a really great set of scissors that enables him to remove
    any single-line snippet from the Moo York Times with one cut. He
    notices that he can cut entire words or phrases with a single cut,
    thus reducing his total number of cuts.
    
    What is the minimum amount of cuts he has to make to construct his
    letter of M (1 <= M <= 50,000) letters?
    
    It is guaranteed that it is possible for FJ to complete his task.
    
    Consider a 38 letter Moo York Times:
    
            THEQUICKBROWNFOXDO
            GJUMPSOVERTHELAZYDOG
    
    from which FJ wants to construct a 9 letter message:
    
            FOXDOG
            DOG
    
    These input lines represent a pair of strings:
    
            THEQUICKBROWNFOXDOGJUMPSOVERTHELAZYDOG
            FOXDOGDOG
    
    Since "FOXDOG" exists in the newspaper, FJ can cut this piece out
    and then get the last "DOG" by cutting out either instance of the
    word "DOG".
    
    Thus, he requires but two cuts.
    
    PROBLEM NAME: letter
    
    INPUT FORMAT:
    
    * Line 1: Two space-separated integers: N and M
    
    * Lines 2..?: N letters laid out on several input lines; this is the
            text of the one copy of the Moo York Times. Each line will
            have no more than 80 characters.
    
    * Lines ?..?: M letters that are the text of FJ's letter. Each line
            will have no more than 80 characters.
    
    SAMPLE INPUT (file letter.in):
    
    38 9
    THEQUICKBROWNFOXDO
    GJUMPSOVERTHELAZYDOG
    FOXDOG
    DOG
    
    OUTPUT FORMAT:
    
    * Line 1: The minimum number of cuts FJ has to make to create his
            message
    
    SAMPLE OUTPUT (file letter.out):
    
    2
    

    一看跟子串相关,就是后缀那一套了。想法是这样的,尽量在文本串中找到更长的子串与当前串匹配。若无法继续匹配了,则重新匹配,答案+1。这里我选择了后缀自动机,实现起来好写。

    #include <cstdio>
    #include <cstring>
    
    const int maxn = 50005;
    
    int n, m, ans, now;
    int sam[maxn << 1][26], len[maxn << 1], link[maxn << 1], sz, last, p, q, cur, clone;
    char ch;
    
    int main(void) {
    	freopen("letter.in", "r", stdin);
    	freopen("letter.out", "w", stdout);
    	scanf("%d%d", &n, &m);
    	link[sz++] = -1;
    	for (int i = 1; i <= n; ++i) {
    		while ((ch = getchar()) < 'A');
    		cur = sz++;
    		len[cur] = len[last] + 1;
    		for (p = last; p != -1 && !sam[p][ch - 'A']; p = link[p]) {
    			sam[p][ch - 'A'] = cur;
    		}
    		if (p != -1) {
    			q = sam[p][ch - 'A'];
    			if (len[p] + 1 == len[q]) {
    				link[cur] = q;
    			}
    			else {
    				clone = sz++;
    				memcpy(sam[clone], sam[q], sizeof sam[0]);
    				link[clone] = link[q];
    				len[clone] = len[p] + 1;
    				for (; p != -1 && sam[p][ch - 'A'] == q; p = link[p]) {
    					sam[p][ch - 'A'] = clone;
    				}
    				link[q] = link[cur] = clone;
    			}
    		}
    		last = cur;
    	}
    	
    	for (int i = 1; i <= m; ++i) {
    		while ((ch = getchar()) < 'A');
    		now = sam[now][ch - 'A'];
    		if (!now) {
    			++ans;
    			now = sam[0][ch - 'A'];
    		}
    	}
    	if (now) {
    		++ans;
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    

      这也算是SAM的模版了叭。

  • 相关阅读:
    Eclipse建立Java工程中的三个JRE选项的区别(Use an execution environment JRE,Use a project specific JRE,Use default JRE)
    Maven项目报错:Missing artifact****和ArtifactDescriptorException: Failed to read artifact descriptor for***和Cannot change version of project facet Dynamic web module to 2.5
    使用jdk的keytool 生成CA证书的方法
    Linux shell逐行读取文件的方法
    ArrayList的实现原理
    时间复杂度总结
    RPC的原理总结
    hashcode和equals方法的区别和联系
    消息队列的应用场景总结
    Java中IO流中的装饰设计模式(BufferReader的原理)
  • 原文地址:https://www.cnblogs.com/ciao-sora/p/6040791.html
Copyright © 2011-2022 走看看