列表

详情


NC19882. [AHOI2008]Y型项链

描述

小可可得到了一个可爱的Y型项链。小可可现在的项链是这个样子的:项链的最中间有一颗大珍珠作为结合点,从大珍珠上连出来3条由各种宝石串起来的链子。小可可希望让这3个链子完全一样,她每次可以从一端取下来一个宝石,或者从一端安上去一个宝石。假设小可可每种宝石都有无数多个,小可可希望用尽量少的操作次数得到想要的Y型项链。小可可对于所得到的Y型项链的宝石数没有特殊的要求,所以即使你把所有宝石都弄下来了,也是一个可以接受的方案(三根光秃秃的绳子也是完全一样的)。 换句话说,给你3个字符串,你每一次可以向一个字符串的末端删除一个字符或添加一个字符,你需要用尽量少的操作次数使得这3个字符串变成一样的。 

输入描述

一共有3行,每行有一个数字N,表示Y型项链的这个链子有N个宝石,然后是一个空格,然后是N个'A'和'Z'之间的字符,表示这个链子上的宝石,每个字母表示一种不同的宝石,这个字符串最左边的字符表示的是离大珍珠最近的那个宝石,而最右边的表示的是在顶端的宝石。

输出描述

只有一个整数:小可可所需要的最少的操作次数。

示例1

输入:

3 CAT
3 TAC
5 CATCH

输出:

8

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 24ms, 内存消耗: 496K, 提交时间: 2019-04-16 20:12:05

#include<bits/stdc++.h>
using namespace std;
int n[5],tot,ans=1e9;
string s[5],g;
int Calc(int id)
{
    int len=0;
    for(int i=1;i<=min(tot,n[id]);i++) if(g.substr(0,i)==s[id].substr(0,i)) len=i;
    int res=n[id]-len+tot-len;
    return res;
}
int main()
{
    for(int i=1;i<=3;i++) 
		cin>>n[i]>>s[i];
    for(int i=1;i<=3;i++)
        for(int j=0;j<=n[i];j++)
            for(int k=0;k<n[i]-j+1;k++)
            {
                g=s[i].substr(k,j);
                tot=j;
                int res=Calc(1)+Calc(2)+Calc(3);
                ans=min(ans,res);
            }
    ans=min(ans,n[1]+n[2]+n[3]);
    printf("%d\n",ans);
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 4ms, 内存消耗: 504K, 提交时间: 2020-03-10 13:29:40

#include<cstdio>
int l1,l2,l3,c;
int ans;
char s1[51],s2[51],s3[51],ch;
void chk()
{
	for(int i=1;i<=l1;i++)
	{
		int m1=0,m2=0;
		while(s1[m1]==s2[m1]&&m1<i) m1++;
		while(s1[m2]==s3[m2]&&m2<i) m2++;
		int v=l1+i+l2-m1*2+l3-m2*2;
		if(ans>v) ans=v;
	}
}
int main()
{
	scanf("%d%s%d%s%d%s",&l1,s1,&l2,s2,&l3,s3);
	ans=l1+l2+l3;
	chk();
	c=l1;l1=l2;l2=c;
	for(int i=0;i<51;i++)
	{
		ch=s1[i];
		s1[i]=s2[i];
		s2[i]=ch;
	}
	chk();
	c=l1;l1=l3;l3=c;
	for(int i=0;i<51;i++)
	{
		ch=s1[i];
		s1[i]=s3[i];
		s3[i]=ch;
	}
	chk();
	printf("%d",ans);
	return 0;
}

上一题