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

这样是一个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 = ;
const int MAXLEN = ;
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 << ];
vector<S> v;
void kmp_pre(char t[])
{
int j, k;
int tlen = strlen(t);
k = -, j = ; nxt[] = -;
while (j < tlen)
{
if (k == - || 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 = , j = ;
kmp_pre(t);
while (i < slen)
{
if (j == - || s[i] == t[j])
{
i++;
j++;
}
else j = nxt[j];
if (j == tlen)
{
ret.push_back(i-);
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 = ;
for (int i = ; i < n; i++)
{
scanf("%s", emo[i]);
}
getchar();
for (int i = ; i < m; i++)
{
gets(str);
v.clear();
for (int j = ; j < n; j++)
{
vector<int> pos;
int len = strlen(emo[j]);
pos = kmp(str, emo[j]);
for (int k = ; k < pos.size(); k++)
{
v.push_back(S(pos[k]-len+, 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 = ;
if (!v.empty()) ans++;
for (int j = ; j < v.size(); j++)
{
if (v[j].l > v[crt].r)
{
crt = j;
ans++;
}
}
}
cout << ans << endl;
}
return ;
}

HDU1936 [贪心+KMP] 点的区间覆盖的更多相关文章

  1. codeforces Gym 100187F F - Doomsday 区间覆盖贪心

    F. Doomsday Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/F ...

  2. 高效算法——E - 贪心-- 区间覆盖

    E - 贪心-- 区间覆盖 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/E 解题思路: 贪心思想, ...

  3. UVa 10020 - Minimal coverage(区间覆盖并贪心)

    Given several segments of line (int the X axis) with coordinates [Li, Ri]. You are to choose the min ...

  4. 贪心算法----区间覆盖问题(POJ2376)

    题目: 题目的大概意思是约翰这个农民有N条牛,这些牛可以在一天中的某个时间段可以进行工作,他想把这个时间段分成若干个片段让这些牛去进行打扫任务,你的任务是安排尽量少的牛然后可以完成分成这些片段的打扫任 ...

  5. UVA 10382 Watering Grass(区间覆盖,贪心)题解

    题意:有一块草坪,这块草坪长l 米,宽 w 米,草坪有一些喷头,每个喷头在横坐标为 p 处,每个喷头的纵坐标都是(w/2) ,并且喷头的洒水范围是一个以喷头为圆心,半径为 r 米的圆.每次最少需要打开 ...

  6. UVa 10382 Watering Grass (区间覆盖贪心问题+数学)

    题意:有一块长为l,宽为w的草地,在其中心线有n个喷水装置,每个装置可喷出以p为中心以r为半径的圆, 选择尽量少的装置,把草地全部润湿. 析:我个去啊,做的真恶心,看起来很简单,实际上有n多个坑啊,首 ...

  7. POJ 2376 Cleaning Shifts (贪心,区间覆盖)

    题意:给定1-m的区间,然后给定n个小区间,用最少的小区间去覆盖1-m的区间,覆盖不了,输出-1. 析:一看就知道是贪心算法的区间覆盖,主要贪心策略是把左端点排序,如果左端点大于1无解,然后, 忽略小 ...

  8. 贪心问题:区间覆盖 POJ 1328 Rader Installation

    题目:http://poj.org/problem?id=1328 题意:给定海岛个数,雷达半径,输入各个海岛坐标,求能覆盖所有海岛的最少雷达数 题解: 1. 贪心的区间覆盖问题,尽量让每个雷达覆盖更 ...

  9. 贪心问题:区间覆盖 NYOJ 喷水装置(二)

    喷水装置(二) 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水 ...

随机推荐

  1. Python——for表达式

    一.for表达式 1.for表达式语法格式及用法 for表达式利用可迭代对象创建新的列表,for表达式也称为列表推导式,具体语法格式如下: [表达式 for 循环计数器 in 可迭代对象] 例: a ...

  2. Java动画 重力弹球 如鹏游戏引擎 精灵 设计一个小球加速落地又减速弹起并反复直到停止的Java程序

    package com.swift; import com.rupeng.game.GameCore; public class BouncingBall implements Runnable { ...

  3. python @staticmethod和@classmethod

    Python其实有3个方法,即 静态方法 (staticmethod), 类方法 (classmethod)和 实例方法. 如下: def foo(x): print "executing ...

  4. NOIP模拟赛 魔方

    [题目描述] ccy(ndsf)觉得手动复原魔方太慢了,所以他要借助计算机. ccy(ndsf)家的魔方都是3*3*3的三阶魔方,大家应该都见过. (3的“顺时针”改为“逆时针”,即3 4以图为准.) ...

  5. 洛谷 2387/BZOJ 3669 魔法森林

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 3765  Solved: 2402[Submit][Statu ...

  6. charles 模拟手机弱网、修改请求参数、修改返回值

    1.charles模拟弱网(断网) 2.charles修改请求参数 (1)先访问一次需要改的请求,在charles上找到相应的请求地址 (2)然后在需要打断点的请求上右键,勾选[Breakpoints ...

  7. php通过geohash算法实现查找附近的商铺

    geohash有以下几个特点: 首先,geohash用一个字符串表示经度和纬度两个坐标.利用geohash,只需在一列上应用索引即可. 其次,geohash表示的并不是一个点,而是一个矩形区域.比如编 ...

  8. C与C++接口相互调用

    转载于:http://blog.csdn.net/lincoln_2012/article/details/50801080 项目中经常使用C和C++混合编程,那么,在调用对方接口时,总是不可避免地出 ...

  9. Spring boot 中Spring data JPA的应用(一)

    最近一直在研究Spring Boot,今天为大家介绍下Spring Data JPA在Spring Boot中的应用,如有错误,欢迎大家指正. 先解释下什么是JPA JPA就是一个基于O/R映射的标准 ...

  10. Hive学习笔记(四)-- hive的桶表

    桶表抽样查询 查看hdfs上对应的文件内容 一个两个桶,第一个桶和第三个桶的数据 task = 4 4 / 2 = 2,一共是两个桶 第1个桶,第1+2个桶