本文已参与[新人创作礼]活动,一起开启掘金创作之路
题目描述
这是4月18日代码源div2的每日一题。
真假字符串 - 题目 - Daimayuan Online Judge
给定两个长度相等的字符串 S1,S2, 问能否找出一个字符串 S, 使得 S 只删除一个字符可以得到 S1, 并且 S 只删除一个字符也可以得到 S2 (可以是不同位置的字符)。
输入格式 输入第一行给出字符串 S1, 第二行给出字符串 S2, 两个字符串的长度 1≤len≤300000。
输出格式 如果能找到满足条件的字符串 S, 输出 1, 否则输出 0。
样例输入 abacaa aacaba 样例输出 1 样例解释 abacaba 删除第二个字符 b 可以得到字符串 S1, 并且删除第一个字符 b 可以得到字符串 S2。
问题解析
如果题目说的,有一个字符串s可以通过删除一个字符得到s1和s2,那说明要么s1和s2相等(s删除的地方一样),要么说明s1和s2有一处地方不一样(s删除的地方不一样),即我们可以把题目转化成:s1和s2是否可以最多删除一个字符后相等。
我们先遍历一下两个字符串,找第一个不相同的地方,如果没有,说了s1和s2相同,我们直接输出1。如果有不相同的地方,则要分两种情况讨论了:
1、我们删掉s1的一个字符,然后继续比较s1和s2,如果找到下一处地方不一样,就删除s2的一个字符,经过这次删除后如果两个字符串相同了就是1,不然我们就看第二种情况。
2、我们删掉s2的一个字符,然后继续比较s1和s2,如果找到下一处地方不一样,就删除s1的一个字符,经过这次删除后如果两个字符串相同了就是1,反之是0。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#define endl '\n';
typedef long long ll;
typedef pair<int, int> PII;
bool dfs(string s1, string s2)
{
int n = s1.size(),l=0,r=0;
bool st = true;
while (l < n && r < n)
{
if (s1[l] != s2[r])
{
if (st)
{
l++;
st = false;
}
else return false;
}
else l++, r++;
}
if (l < n)return false;
return true;
}
int main()
{
string s1, s2;
cin >> s1 >> s2;
int n = s1.size(), ans = -1;
for (int i = 0; i < n; i++)
{
if (s1[i] != s2[i])
{
ans = i;
break;
}
}
if (ans == -1)
{
cout << 1 << endl;
}
else
{
string str1 = s1, str2 = s2;
str1.erase(ans,1);
str2.erase(ans,1);
if (dfs(s2, str1) || dfs(s1, str2))
{
cout << 1 << endl;
}
else cout << 0 << endl;
}
return 0;
}