字符串dfs

第一题

牛客网寒训第四场 #I--回文串

题目描述

自从 Applese 学会了字符串之后,精通各种字符串算法,比如……判断一个字符串是不是回文串。

这样的题目未免让它觉得太无聊,于是它想到了一个新的问题。

如何判断一个字符串在任意位置(包括最前面和最后面)插入一个字符后能不能构成一个回文串?

输入描述:

仅一行,为一个由字母和数字组成的字符串 s。

输出描述:

如果在插入一个字符之后可以构成回文串,则输出"Yes", 否则输出"No"。

示例1

输入
applese

输出
No

示例2

输入
java

输出
Yes

备注:

|s| ≤ 10^5

思路:其实是模仿下面那题敲出来的,没想到过了,开心!其实是前后同时进行搜索,碰到第一个不同的,可以分两种情况,一是选择右边插入,左边下标+1,右边不变,插入数cnt+1;二是选择左边插入,左边下标不变,右边下标-1,插入数cnt+1。递归出口是cnt>1,要注意判断插入一个字符是否可以成为回文串的条件是左边的下标要大于字符串长度的一半+1(这个当时一直弄错),忽然发现用深搜做这种题挺简单的。

AC代码

#include 
#include 
#include 
using namespace std;
 
string str;
bool flag;
int len;
 
void dfs(int a, int b, int cnt)
{
    if(cnt > 1) return ;
    int tt = len/2;
    if(a == tt+1 ) flag = true;
    if(str[a] == str[b])
        dfs(a+1, b-1, cnt);
    else{
        dfs(a+1, b, cnt+1); //右边插入
        dfs(a, b-1, cnt+1); //左边插入
    }
}
 
int main()
{
    while(cin >> str){
        flag = 0;
        len = str.length();
        dfs(0, len-1, 0);
        if(flag) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    return 0;
}

第二题

2019牛客网寒训第二场#G -- 复读机

题目描述

一天,处女座在牛客算法群里发了一句“我好强啊”,引起无数的复读,可是处女座发现复读之后变成了“处女座好强啊”。处女座经过调查发现群里的复读机都是失真的复读机,会固定的产生两个错误。一个错误可以是下面的形式之一:

  1. 将任意一个小写字母替换成另外一个小写字母
  2. 在任意位置添加一个小写字母
  3. 删除任意一个字母

处女座现在在群里发了一句话,他收到了一个回应,他想知道这是不是一个复读机。

输入描述:

两行
第一行是处女座说的话s
第二行是收到的回应t
s和t只由小写字母构成且长度小于100

输出描述:

如果这可能是一个复读机输出”YES”,否则输出”NO”

示例1

输入
abc
abcde

输出
YES

说明
abc->abcd->abcde

示例2

输入
abcde
abcde

输出
YES

说明
abcde->abcdd->abcde

备注:

只要能经过两步变换就从s得到t就有可能是复读机。

思路:方法基本同上面,不过这是比较两个字符串的,cnt计算累计产生的错误的数量,递归出口是cnt大于2,有三种情况,【替换】字符下标都+1,cnt+1;【删除】前+1,后不变,cnt+1;【添加】前不变,后+1,cnt+1。如果两个字符串都能搜索完,则是复读机。

代码:

#include 
#include 
#include 
#include 
#include 
using namespace std;
 
string s, t;
bool flag;
int slen, tlen;
 
int dis(int a, int b)
{
    return a > b ? a-b : b-a;
}
 
void dfs(int ss, int tt, int cnt) //cnt是累计产生的错误的数量
{
    if(cnt > 2) return;
    if(ss == slen && tt == tlen) flag = true;
    if(s[ss] == t[tt])
        dfs(ss+1, tt+1, cnt);  //某个字符相同则继续判断
    else{
        dfs(ss+1, tt+1, cnt+1); //替换,错误数+1
        dfs(ss+1, tt, cnt+1);  //删除
        dfs(ss, tt+1, cnt+1);  //添加
    }
}
 
int main()
{
    while (cin >> s >> t)
    {
        flag = false;
        slen = s.length();
        tlen = t.length();
        if(dis(slen, tlen) <= 2) dfs(0,0,0);
        if(flag) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}

你可能感兴趣的:(字符串dfs)