2017年浙江中医药大学大学生程序设计竞赛(重现赛)C - 寻找zcmu

题目描述

一年一度的浙江中医药大学程序设计校赛正在火热进行,举办至今这是第十一届校赛了。
那么今年就来寻找一下zcmu。
这里有一串只包含小写字母的字符串,里面有若干个zcmu,你为了省力,需要知道最少需要删除几个字符是的有连续四个字符是"zcmu"。
 

输入描述:

多组数据
每组数据包含一个字符串
1 <= n <= 100000

输出描述:

输出一个整数表示最少需要删除的字符数,若不存在则输出"-1"。
示例1

输入

zcmu
umcz
zzccmmuuaa

输出

0
-1
2

题解

$dp$。

先处理$z$,然后处理$c$,然后处理$m$,最后处理$u$。每个字母处理的时候计算离得最近的上一种字母。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 100000 + 10;
char s[maxn];
int dp[maxn][4];
int pre[maxn];

int main() {
  while(~scanf("%s", s)) {
    for(int i = 0; s[i]; i ++) {
      for(int j = 0; j < 4; j ++) {
        dp[i][j] = 200000;
      }
    }

    int pos;
//--- z
    pos = -1;
    for(int i = 0; s[i]; i ++) {
      if(s[i] == 'z') {
        dp[i][0] = i;
        pos = i;
      }
      pre[i] = pos;
    }
//--- c
    for(int i = 0; s[i]; i ++) {
      if(s[i] == 'c' && pre[i] != -1) {
        dp[i][1] = dp[pre[i]][0];
      }
    }
    pos = -1;
    for(int i = 0; s[i]; i ++) {
      if(s[i] == 'c') pos = i;
      pre[i] = pos;
    }
//--- m
    for(int i = 0; s[i]; i ++) {
      if(s[i] == 'm' && pre[i] != -1) {
        dp[i][2] = dp[pre[i]][1];
      }
    }
    pos = -1;
    for(int i = 0; s[i]; i ++) {
      if(s[i] == 'm') pos = i;
      pre[i] = pos;
    }
//--- u
    for(int i = 0; s[i]; i ++) {
      if(s[i] == 'u' && pre[i] != -1) {
        dp[i][3] = dp[pre[i]][2];
      }
    }

    int ans = 200000;
    for(int i = 0; s[i]; i ++) {
      if(s[i] == 'u') {
        if(dp[i][3] != 200000) {
          ans = min(ans, i - dp[i][3] + 1 - 4);
        }
      }
    }
    if(ans == 200000) ans = -1;
    printf("%d\n", ans);
  }
  return 0;
}

  

posted @ 2017-12-21 15:08  Fighting_Heart  阅读(400)  评论(0编辑  收藏  举报