zoukankan      html  css  js  c++  java
  • HDU 1936 区间贪心

    /*
     *区间贪心。前几天刚做了POJ 1328 ...思路完全相同...
     *最多有100个表情,100行文字。遍历寻找每个表情的所在区间。时间复杂度大约在10^5 ~ 10^6 可以接受。
     *然后对每个表情按照右坐标排序。改变表情的最右边的字符。贪心判断是否更改。

     *(⊙o⊙)… 每一行的里的表情可能是重复的。所以判断每行要更改的最少字母数。最后求和。很傻逼的全都放一起了。然后。。。。幸福的wa了。
     */

      1 #include<stdio.h>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<string.h>
      5 using namespace std;
      6 
      7 char emo[110][20];
      8 char txt[110][110];
      9 int n, m;
     10 int cnt;
     11 int ans;
     12 
     13 struct E
     14 {
     15     int l, r;
     16 } e[10010];
     17 
     18 int cmp(E a, E b)
     19 {
     20     if (a.l != b.l)
     21         return a.l < b.l;
     22     return a.r < b.r;
     23 }
     24 
     25 void ask()
     26 {
     27     for (int i=0; i<m; ++i)  // 遍历文档
     28     {
     29         int lent = strlen(txt[i]);
     30         cnt = 1;
     31         for (int j=0; j<lent; ++j)
     32         {
     33             for (int k=0; k<n; ++k)  //遍历表情看是否在当前文档中
     34             {
     35                 bool flag = false;
     36                 int lene = strlen(emo[k]);
     37                 if (j+lene-1 > lent) continue;
     38                 if (txt[i][j] == emo[k][0] && txt[i][j+lene-1] == emo[k][lene-1])
     39                 {
     40                     flag = true;
     41                     for (int p=0; p<lene; ++p)
     42                     {
     43                         if (txt[i][j+p] != emo[k][p])
     44                         {
     45                             flag = false;
     46                             break;
     47                         }
     48                     }
     49                     if (flag)
     50                     {
     51                         e[cnt].l = j;
     52                         e[cnt++].r = j+lene-1;
     53                     }
     54                 }
     55             }
     56         }
     57        e[0].l = e[0].r = -100;  // 然而我也不太明白为什么要加上e[0]。
     58         sort(e+1, e+cnt, cmp); // 对每个表情按照区间右边的值从大到小排序。
     59 
     60         for (int i=cnt-1; i>=1; --i)  // 从后往前遍历。如果上一个的右端点小于当前左端点。ans++。破坏下一个的右端点。
     61         {
     62             if (e[i].l > e[i-1].r)
     63                 ans += 1;
     64             else
     65             {
     66                 for (int j=i-1; j>=1; --j)  // 否则直到找到第一个右端点小于当前左端点的位置。破坏它的右端点。ans++。
     67                 {
     68                     if (e[i].l <= e[j].r);
     69                     else
     70                     {
     71                         i = j+1;  // 循环结束后还要i--。所以i= j+1。 实际上就是i = j。
     72                         ans += 1;
     73                         break;
     74                     }
     75                 }
     76             }
     77         }
     78 
     79     }
     80 }
     81 
     82 int main()
     83 {
     84     while(cin >> n >> m)
     85     {
     86         if (n == 0 && m == 0) break;
     87         for (int i=0; i<n; ++i)
     88         {
     89             cin >> emo[i];
     90         }
     91         getchar();
     92         for (int i=0; i<m; ++i)
     93         {
     94             gets(txt[i]);
     95         }
     96         ans = 0;
     97         ask();  //遍历寻找每个表情的区间范围
     98         cout << ans << endl;
     99     }
    100     return 0;
    101 }
    View Code



  • 相关阅读:
    面向消息的持久通信与面向流的通信
    通信协议
    [1]序章,基本
    深拷贝和浅拷贝
    堆/栈 内存管理相关
    C++的四种cast(显示类型转换)
    智能指针相关
    C++对象模型:单继承,多继承,虚继承
    HTTP/TCP
    [读书笔记] 为什么绝不在构造/析构函数中调用virtual函数
  • 原文地址:https://www.cnblogs.com/icode-girl/p/4683425.html
Copyright © 2011-2022 走看看