zoukankan      html  css  js  c++  java
  • HDU1936 [贪心+KMP] 点的区间覆盖

    每一行对话分别取匹配所有的表情

    这样是一个n**2的匹配,可以用KMP 找出每行对话中的每个表情的左右端点

    这样相当于就是问用最少多少个点 可以覆盖所有的区间(每个区间中放一个点表示覆盖)

    贪心 按右端点升序排列 相同时左端点也升序(这里其实没有影响但是 按照匹配上来讲 应该按照升序)

    --理由:

    --> 如果当前所指区间的后面两个区间的右端点相同 那么应该是先比较左端点较小的那个区间 

    但是因为后面两个区间的右端点相同那么一定是相互覆盖的 所以对结果没有影响

    然后 if (strict[crt].r < strict[next]) .l )  //区间不重叠

       {ans++; crt = next;} 

    代码君:

    #include <bits/stdc++.h>
    #include <string.h>
    #include <iostream>
    #include <stdio.h>
    
    
    using namespace std;
    
    const int MAXN = 107;
    const int MAXLEN = 107;
    char emo[MAXN][MAXLEN];
    char str[MAXLEN];
    
    struct S
    {
        int l, r;
        S() {}
        S(int l, int r) : l(l), r(r) {}
        bool operator < (S s1) const 
        {
            if (r != s1.r) return r < s1.r;
            return l < s1.l;
        }
    };
    
    int n, m;
    int nxt[MAXN << 1];
    vector<S> v;
    void kmp_pre(char t[])
    {
        int j, k;
        int tlen = strlen(t);
        k = -1, j = 0; nxt[0] = -1;
        while (j < tlen)
        {
            if (k == -1 || t[j] == t[k]) nxt[++j] = ++k;
            else k = nxt[k];
        }
    }
    vector<int> kmp(char s[], char t[])
    {
        int slen = strlen(s), tlen = strlen(t);
        vector<int> ret;
        int i = 0, j = 0;
        kmp_pre(t);
        while (i < slen)
        {
            if (j == -1 || s[i] == t[j]) 
            {
                i++;
                j++;
            }
            else j = nxt[j];
            if (j == tlen)
            {
                ret.push_back(i-1);
                j = nxt[j];
            }
        }
        return ret;
    }
    int lidx[MAXN], ridx[MAXN];
    int main()
    {
        //freopen("in.txt", "r", stdin);
        while (~scanf("%d%d", &n, &m))
        {
            if (!n && !m) break;
            int ans = 0;
            for (int i = 0; i < n; i++)
            {
                scanf("%s", emo[i]);
            }
            getchar();
            for (int i = 0; i < m; i++)
            {
                gets(str);
                v.clear();
                for (int j = 0; j < n; j++)
                {
                    vector<int> pos;
                    int len = strlen(emo[j]);
                    pos = kmp(str, emo[j]);
                    for (int k = 0; k < pos.size(); k++)
                    {
                        v.push_back(S(pos[k]-len+1, pos[k]));
                    }                
                }
                sort(v.begin(), v.end());/*
                for (int i = 0; i < v.size(); i++) cout << v[i].l << " " << v[i].r << endl;
                return 0;*/
                int crt = 0;
                if (!v.empty()) ans++;
                for (int j = 1; j < v.size(); j++)
                {
                    if (v[j].l > v[crt].r) 
                    {
                        crt = j;
                        ans++;
                    }
                }
            }
            cout << ans << endl;
         }
        return 0;
    }
    View Code
  • 相关阅读:
    安卓打包名称
    安卓判断麦克风权限
    Redis基础了解
    Redis的安装
    SVN的日常使用和安装
    Maven基础2
    Maven基础1
    ResultSet的Type
    Hibernate高级查询QBC条件设置——Restrictions用法 引自:http://www.cnblogs.com/evon168/archive/2010/10/29/1863059.html
    Spring配置事务 http://www.cnblogs.com/leiOOlei/p/3725911.html
  • 原文地址:https://www.cnblogs.com/oscar-cnblogs/p/8527806.html
Copyright © 2011-2022 走看看