2 solutions
-
0
Guest MOD
-
0
贪心捏
题目大意
给三条字符串,只能在最后删除或添加字符 求最少多少次能使三条相同
考虑样例
输入样例:
3 CAT 3 TAC 5 CATCH
ans= 8
一眼丁真,看到CAT重复了两遍 显然改变CAT是最劣的 改变CAT所需的步骤是改变TAC的两倍 所以理应改变TAC (以下将最长的重复的部分称为 最长公共前缀)
CH直接删掉就好啦
可以看出来 对于重复的部分 我们不做任何处理是最优的 而对于剩下的那条“另类” 直接把他变成我们想要的样子就好了
而多余的部分 我们可以证明多余的部分一定是不同的或唯一的 否则它也是最长公共前缀的一部分了 设n1,n2为最长公共前缀所在的两部分的长度,最长公共前缀长度为ans1 那么可以直接把最终答案num=n1+n2-2ans1 而对于剩下的字符串来说 num+= n3(删掉全部的长度)+ans1(全部改成最长公共前缀)-ans22(可能与最长公共前缀有重复的部分得减去这部分)
个人认为已经很详尽了 数据很水 或许其他做法也能过 甚至有的错误代码也能过......
Code
#include <iostream> using namespace std; int n1,n2,n3,ans1,ans3,ans2; int num; char a[52],b[52],c[52]; int main() { cin>>n1; for(int i=1;i<=n1;i++) cin>>a[i]; cin>>n2; for(int i=1;i<=n2;i++) cin>>b[i]; cin>>n3; for(int i=1;i<=n3;i++) cin>>c[i]; for(int i=1;i<=min(n1,n2);i++) if(a[i]==b[i]) ans1++; else break; for(int i=1;i<=min(n1,n3);i++) if(c[i]==a[i]) ans2++; else break; for(int i=1;i<=min(n2,n3);i++) if(b[i]==c[i]) ans3++; else break; if(ans1>=max(ans2,ans3)) { num=(n1+n2-2*ans1); num+=(n3+ans1-ans2*2); } else if(ans2>=max(ans1,ans3)) { num=(n1+n3-2*ans2); num+=(n2+ans2-ans3*2); } else { num=(n2+n3-2*ans3); num+=(n1+ans3-ans1*2); } cout<<num; return 0; }
Information
- ID
- 253
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 4
- Tags
- (None)
- # Submissions
- 20
- Accepted
- 17
- Uploaded By