嘟嘟嘟

因为只有三个字符串,所以就有一个比较暴力的做法:枚举这三个串所有排列,然后对于每一个排列,减去这三个串两两的公共部分的长度,更新答案。

求公共部分自然想到kmp:比如s[1]接在s[0]后面,那么我们只用把s[0]和s[1]匹配,把s[1]当做模式串,s[0]当做文本串,当s[0]匹配到头的时候,看s[1]匹配到哪,就是这两个串的公共长度。

那么就会有s[1]是s[0]的子串的情况,这时候只记录s[0[的长度,然后再减去s[0]和s[2]的公共长度(我就是因为刚开始忘减了wa了几发)。

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 1e5 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = ans * + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} char s[][maxn];
int len[], f[][maxn], kmp[][]; void init(int m, char *s, int id)
{
f[id][] = ;
for(int i = , j = ; i <= m; ++i)
{
while(s[j + ] != s[i] && j) j = f[id][j];
if(s[j + ] == s[i]) j++;
f[id][i] = j;
}
}
int KMP(int n, int m, char *s1, char *s2, int id)
{
int j = ;
for(int i = ; i <= n; ++i)
{
while(s2[j + ] != s1[i] && j) j = f[id][j];
if(s2[j + ] == s1[i]) j++;
if(j == m) return -;
}
return j;
} int main()
{
scanf("%s%s%s", s[] + , s[] + , s[] + );
int ans = INF;
for(int i = ; i < ; ++i) len[i] = strlen(s[i] + );
for(int i = ; i < ; ++i)
{
init(len[i], s[i], i);
for(int j = ; j < ; ++j) if(i != j)
kmp[j][i] = KMP(len[j], len[i], s[j], s[i], i);
//这时候要把i作为文本串,因为j的fail数组还没构造
}
for(int i = ; i < ; ++i)
for(int j = ; j < ; ++j)
for(int k = ; k < ; ++k)
{
if(i == j || j == k || i == k) continue;
int sum = len[i] + len[j] + len[k] - kmp[i][j] - kmp[j][k];
if(kmp[i][j] >= )
{
if(kmp[j][k] >= ) ans = min(ans, sum);
else ans = min(ans, sum - len[k] - );
}
else
{
if(kmp[j][k] >= ) ans = min(ans, sum - len[j] - + kmp[j][k] - kmp[i][k]);//别忘了
else ans = min(ans, len[i]);
}
}
write(ans); enter;
return ;
}

CF25E Test的更多相关文章

  1. CF25E:Test——题解

    https://vjudge.net/problem/CodeForces-25E 题目大意:给三个字符串,求最小串,使得前三个串都是它的子串. ———————————————— 这题虽然是看哈希的时 ...

  2. CF25E-Test【AC自动机,bfs】

    正题 题目链接:https://www.luogu.com.cn/problem/CF25E 题目大意 给出三个串,然后求一个最短的串包含这三个串. \(1\leq |s_1|,|s_2|,|s_3| ...

随机推荐

  1. html自定义垂直导航菜单(加强版--自定义传入menu参数,支持JSONArray、JSArray、JSONObject、JSObject)

    在上一篇中我简单写了个html自定义垂直导航菜单,缺点很明显,里面的数据是固定死的,不能动态更改数据. 这里我重写了一个修改版的垂直二级导航菜单,将原先的menuBox.init(config);修改 ...

  2. python 爬虫系列03--职位爬虫

    职位爬虫 import requests from lxml import etree cookie = { 'Cookie':'user_trace_token=20181015184304-692 ...

  3. qs.parse()、qs.stringify()、JSON.parse()、JSON.stringify()使用方法

    一.JSON.parse(用于从一个字符串中解析出json 对象)ps:单引号写在{}外,每个属性都必须双引号,否则会抛出异常 let str = '[{"field":" ...

  4. pip使用的基本命令

    基本的命令解释,如下图: 安装 sudo easy_install pip 列出已安装的包 pip freeze or pip list 导出requirements.txt pip freeze & ...

  5. 九度oj题目1518:反转链表

    题目1518:反转链表 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:2567 解决:948 题目描述: 输入一个链表,反转链表后,输出链表的所有元素.(hint : 请务必使用链表) ...

  6. .net mvc 设置div的动态部分视图内容 dynamic partial view

    示例效果:点击按钮,在div中 显示不同的partial view的内容 $("#btnEdit").click(function () { //动态获取相应的部分视图 var u ...

  7. RocketMQ3.2.6安装部署及调用

    RocketMQ3.2.6安装部署及调用 1.RocketMQ部署架构 所有IP都是127.0.0.1,其中NameServer一个,Broker一个,Producer一个,Consumer一个 2. ...

  8. 分支结构if……else

    语法: if(条件) 语句或语句块1 end else begin 语句或者语句块2 end 特点: . else并不一定是必须的. . 如否条件为真,将执行语句和语句块1,条件为假时执行语句或语句块 ...

  9. 使用ANY、Some或All关键字

    可以使用All或Any关键字修改引入子查询的比较运算符.Some是与Any等效的ISO标准,All要求Where表达式与子查询返回的每个值进行比较时都应满足比较条件,Any则要求Where表达式与子查 ...

  10. 位运算(6)——Number Complement

    Given a positive integer, output its complement number. The complement strategy is to flip the bits ...