题意:
给出一个串,可以从任意地方截取,然后把两部分位置换下得到新的串,问从a串变到b串有多少种方法。
题解:
首先我们分析这种变换产生的结果,发现无论怎么变换一个串只能变成和自己不同的len-1个串,而且之后的变化不会出现新的串。这个结论是关键。
然后我们分析下,有原串可以变成len-1个非原串,每个非原串又可以变成1个原串,和len-2个非原串。那么我们方向来分析下,一个原串是可以由len-1个非原串变来,一个非原串可以有len-2个非原串变来。
dp[i][0] = dp[i-1][1]*(len-1);
dp[i][1] = dp[i-1][0] + dp[i-1][1]*(len-2);
dp[i][0]表示用了i步变成原串的个数,dp[i][1]表示用了i步变成非原串的个数。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<map>
using namespace std;
typedef long long lld;
const int oo=0x3f3f3f3f;
const lld OO=1LL<<61;
const lld MOD=1000000007;
#define eps 1e-6
#define maxn 100005
lld dp[2][2];
char st[2005],se[1005];
int main()
{
int n;
while(scanf("%s%s",st,se)!=EOF)
{
scanf("%d",&n);
int len=strlen(st);
for(int i=0;i<len;i++)
{
st[i+len]=st[i];
}
dp[0][0]=1;
dp[0][1]=0;
int cur=1;
for(int i=1;i<=n;i++,cur^=1)
{
dp[cur][0]=((len-1)*dp[cur^1][1]+MOD)%MOD;
dp[cur][1]=(dp[cur^1][0]+(len-2)*dp[cur^1][1]+MOD)%MOD;
}
cur^=1;
lld ans=0;
for(int i=0;i<len;i++)
{
int pos=i;
for(int j=0,k=i;j<len;k++,j++)
{
if(st[k]!=se[j])
{
pos=-1;
break;
}
}
if(pos!=-1)
{
if(pos==0)
ans=(ans+dp[cur][0]+MOD)%MOD;
else
ans=(ans+dp[cur][1]+MOD)%MOD;
}
}
cout<<ans<<endl;
}
return 0;
}
/**
ab
ab
2
ababab
ababab
1
ab
ba
2
*/