题目链接
题意:交换一个字符串中的两个字符,使之成为另一个字符串,求最少的步骤。
思路:
如果Si=Tj;这显然不需要进行操作。
如果Si=Tj,Ti=Sj;我们可以进行一次操作将两个配对.
如果Si=Tj,Sj=Tk,Tk=Si; 我们可以两次操作配对。
最后剩下的就是四个一组的。根据鸽巢原理我们一定可以在 3 次操作之内配对。
那么我们现在只需要记录这四种情况有多少个。总的复杂度为 O(n) 。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <map>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
map<char,int> g;
int main()
{
string s,t;
cin>>s>>t;
int len=s.length();
g['A']=0;
g['C']=1;
g['G']=2;
g['T']=3;
int sum[4][4];
memset(sum,0,sizeof(sum));
for(int i=0;i<len;i++)
if(s[i]!=t[i])
sum[g[s[i]]][g[t[i]]]++;
ll ans=0;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
{
int x=min(sum[i][j],min(sum[j][k],sum[k][i]));
sum[i][j]-=x;
sum[j][k]-=x;
sum[k][i]-=x;
ans+=x*2;
}
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
int x=min(sum[i][j],sum[j][i]);
sum[i][j]-=x;
sum[j][i]-=x;
ans+=x;
}
for(int i=0;i<4;i++)
ans+=sum[i][3]*3;
cout<<ans<<endl;
return 0;
}
题意:
给定两个字符串word1和word2,找到将word1转换为word2所需的最小步骤数。(每个操作计为1步)。
您对单词允许以下3种操作:
a)插入字符
b)删除字符
c)替换字符
思路:动态规划
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
const int maxn=1e6+10;
int main()
{
string s,t;
cin>>s>>t;
int ls,lt;
ls=s.length();
lt=t.length();
vector<vector<int> > g(ls+1,vector<int>(lt+1,0));
for(int i=0;i<=ls;i++)
g[i][0]=i;
for(int i=0;i<=lt;i++)
g[0][i]=i;
for(int i=1;i<=ls;i++)
for(int j=1;j<=lt;j++)
{
if(s[i-1]==t[j-1])
g[i][j]=g[i-1][j-1];
else g[i][j]=min(min(g[i][j-1]+1,g[i-1][j]+1),g[i-1][j-1]+1);
}
cout<<g[ls][lt]<<endl;
return 0;
}