• [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的模版了叭。

  • 相关阅读:
    【5.3】dict的子类
    【5.2】dict的常用方法
    【5.1】dict的abc继承关系
    【4.5】列表推导式、生成器表达式、字典推导式
    【4.4】bisect维护已排序序列
    【4.3】实现可切片的对象
    【4.2】Python序列中+、+=和extend的区别
    【4.1】Python中的序列分类
    【3.12】contextlib简化上下文管理器
    【3.11】Python中的with语句
  • 原文地址:https://www.cnblogs.com/ciao-sora/p/6040791.html
Copyright © 2020-2023  润新知