题目链接:点这里。
Problem Description
After little Jim learned Fibonacci Number in the class , he was very interest in it.
Now he is thinking about a new thing -- Fibonacci String .
He defines : str[n] = str[n-1] + str[n-2] ( n > 1 )
He is so crazying that if someone gives him two strings str[0] and str[1], he will calculate the str[2],str[3],str[4] , str[5]....
For example :
If str[0] = "ab"; str[1] = "bc";
he will get the result , str[2]="abbc", str[3]="bcabbc" , str[4]="abbcbcabbc" …………;
As the string is too long ,Jim can't write down all the strings in paper. So he just want to know how many times each letter appears in Kth Fibonacci String . Can you help him ?
Input
The first line contains a integer N which indicates the number of test cases.
Then N cases follow.
In each case,there are two strings str[0], str[1] and a integer K (0 <= K < 50) which are separated by a blank.
The string in the input will only contains less than 30 low-case letters.
Output
For each case,you should count how many times each letter appears in the Kth Fibonacci String and print out them in the format "X:N".
If you still have some questions, look the sample output carefully.
Please output a blank line after each test case.
To make the problem easier, you can assume the result will in the range of int.
Sample Input
1
ab bc 3
Sample Output
a:1
b:3
c:2
d:0
e:0
f:0
g:0
h:0
i:0
j:0
k:0
l:0
m:0
n:0
o:0
p:0
q:0
r:0
s:0
t:0
u:0
v:0
w:0
x:0
y:0
z:0
【题意】
首先fib数列,我们都知道,是根据前两项的和得到第三项的。然后这里我们用一种更高级的操作,就是直接让字符串进行这个操作,显然会得到一个很长很长的字符串,现在不要你输出最后需要的字符串,而是让你输出最后字符串的各个字母的数量。
【分析】
看到fib,反手就是一个矩阵快速幂。果然是。其实初始的那个矩阵,也就是用来快速幂的矩阵有一点不好想。其实也不麻烦,稍微想想就知道了。
fib数列的矩阵快速幂的递推式是:
显然这里,我们借用这个思想,但是这里的fn是一个26个int的数组。于是我们就直接将快速幂的那个矩阵里面的1直接换成一个26*26的单位矩阵,0换成0矩阵不就行了?so easy!
【代码】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<sstream>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS_1(a) memset(a,-1,sizeof(a))
#define MSinf(a) memset(a,0x3f,sizeof(a))
#define MSfalse(a) memset(a,false,sizeof(a))
#define pin1(a) printf("%d",(a))
#define pin2(a,b) printf("%d %d",(a),(b))
#define pin3(a,b,c) printf("%d %d %d",(a),(b),(c))
#define pll1(a) printf("%lld",(a))
#define pll2(a,b) printf("%lld %lld",(a),(b))
#define pll3(a,b,c) printf("%lld %lld %lld",(a),(b),(c))
#define pdo1(a) printf("%f",(a))
#define pdo2(a,b) printf("%f %f",(a),(b))
#define pdo3(a,b,c) printf("%f %f %f",(a),(b),(c))
#define huiche puts("")
#define inf 0x3f3f3f3f
#define lson (ind<<1),l,mid
#define rson ((ind<<1)|1),mid+1,r
#define uint unsigned int
typedef pair<int,int> PII;
#define A first
#define B second
#define pb push_back
#define mp make_pair
#define ll long long
#define eps 1e-8
inline void read1(int &num) {
char in;
bool IsN=false;
in=getchar();
while(in!='-'&&(in<'0'||in>'9')) in=getchar();
if(in=='-') {
IsN=true;
num=0;
} else num=in-'0';
while(in=getchar(),in>='0'&&in<='9') {
num*=10,num+=in-'0';
}
if(IsN) num=-num;
}
inline void read2(int &a,int &b) {
read1(a);
read1(b);
}
inline void read3(int &a,int &b,int &c) {
read1(a);
read1(b);
read1(c);
}
inline void read1(ll &num) {
char in;
bool IsN=false;
in=getchar();
while(in!='-'&&(in<'0'||in>'9')) in=getchar();
if(in=='-') {
IsN=true;
num=0;
} else num=in-'0';
while(in=getchar(),in>='0'&&in<='9') {
num*=10,num+=in-'0';
}
if(IsN) num=-num;
}
inline void read2(ll &a,ll &b) {
read1(a);
read1(b);
}
inline void read3(ll &a,ll &b,ll &c) {
read1(a);
read1(b);
read1(c);
}
inline void read1(double &num) {
char in;
double Dec=0.1;
bool IsN=false,IsD=false;
in=getchar();
while(in!='-'&&in!='.'&&(in<'0'||in>'9'))
in=getchar();
if(in=='-') {
IsN=true;
num=0;
} else if(in=='.') {
IsD=true;
num=0;
} else num=in-'0';
if(!IsD) {
while(in=getchar(),in>='0'&&in<='9') {
num*=10;
num+=in-'0';
}
}
if(in!='.') {
if(IsN) num=-num;
return ;
} else {
while(in=getchar(),in>='0'&&in<='9') {
num+=Dec*(in-'0');
Dec*=0.1;
}
}
if(IsN) num=-num;
}
inline void read2(double &a,double &b) {
read1(a);
read1(b);
}
inline void read3(double &a,double &b,double &c) {
read1(a);
read1(b);
read1(c);
}
///----------------------------------------------------------------------------------------------------------
struct juzhen
{
int m[52][52];
};
juzhen mul(juzhen a,juzhen b)
{
juzhen c;
MS0(c.m);
rep0(i,0,52)
rep0(j,0,52)
rep0(k,0,52)
c.m[i][k]+=a.m[i][j]*b.m[j][k];
return c;
}
juzhen quick(juzhen a,int b)
{
juzhen c;
MS0(c.m);
rep0(i,0,52) c.m[i][i]=1ll;
while(b)
{
if(b&1)
{
c = mul(c,a);
}
a = mul(a,a);
b>>=1;
}
return c;
}
int T;
char nouse[35];
int str1[30];
int str2[30];
int main() {
// freopen("in.txt","r",stdin);
while(scanf("%d",&T)!=EOF) {
while(T--)
{
MS0(str1);
MS0(str2);
scanf("%s",nouse);
int len = strlen(nouse);
rep0(i,0,len) str1[nouse[i]-'a']++;
scanf("%s",nouse);
len = strlen(nouse);
rep0(i,0,len) str2[nouse[i]-'a']++;
int x;
read1(x);
if(x==0) rep0(i,0,26) printf("%c:%d\n",i+'a',str1[i]);
else if(x==1) rep0(i,0,26) printf("%c:%d\n",i+'a',str2[i]);
else
{
juzhen a;
MS0(a.m);
rep0(i,0,26) a.m[i][i]=a.m[i][i+26]=a.m[i+26][i]=1ll;
a = quick(a,x-1);
rep0(i,0,26)
{
printf("%c:%d\n",i+'a',(a.m[i][i]*str2[i]+a.m[i][i+26]*str1[i]));
}
}
puts("");
}
}
return 0;
}
【分析2】
其实这个题呢,也没有这么麻烦,有一个很水很水的做法,因为里面的k是小于50的,所以就可以直接暴力出来,显然可以过,(心疼我写了半天的矩阵快速幂)。
【代码2】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<sstream>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS_1(a) memset(a,-1,sizeof(a))
#define MSinf(a) memset(a,0x3f,sizeof(a))
#define MSfalse(a) memset(a,false,sizeof(a))
#define pin1(a) printf("%d",(a))
#define pin2(a,b) printf("%d %d",(a),(b))
#define pin3(a,b,c) printf("%d %d %d",(a),(b),(c))
#define pll1(a) printf("%lld",(a))
#define pll2(a,b) printf("%lld %lld",(a),(b))
#define pll3(a,b,c) printf("%lld %lld %lld",(a),(b),(c))
#define pdo1(a) printf("%f",(a))
#define pdo2(a,b) printf("%f %f",(a),(b))
#define pdo3(a,b,c) printf("%f %f %f",(a),(b),(c))
#define huiche puts("")
#define inf 0x3f3f3f3f
#define lson (ind<<1),l,mid
#define rson ((ind<<1)|1),mid+1,r
#define uint unsigned int
typedef pair<int,int> PII;
#define A first
#define B second
#define pb push_back
#define mp make_pair
#define ll long long
#define eps 1e-8
inline void read1(int &num) {
char in;
bool IsN=false;
in=getchar();
while(in!='-'&&(in<'0'||in>'9')) in=getchar();
if(in=='-') {
IsN=true;
num=0;
} else num=in-'0';
while(in=getchar(),in>='0'&&in<='9') {
num*=10,num+=in-'0';
}
if(IsN) num=-num;
}
inline void read2(int &a,int &b) {
read1(a);
read1(b);
}
inline void read3(int &a,int &b,int &c) {
read1(a);
read1(b);
read1(c);
}
inline void read1(ll &num) {
char in;
bool IsN=false;
in=getchar();
while(in!='-'&&(in<'0'||in>'9')) in=getchar();
if(in=='-') {
IsN=true;
num=0;
} else num=in-'0';
while(in=getchar(),in>='0'&&in<='9') {
num*=10,num+=in-'0';
}
if(IsN) num=-num;
}
inline void read2(ll &a,ll &b) {
read1(a);
read1(b);
}
inline void read3(ll &a,ll &b,ll &c) {
read1(a);
read1(b);
read1(c);
}
inline void read1(double &num) {
char in;
double Dec=0.1;
bool IsN=false,IsD=false;
in=getchar();
while(in!='-'&&in!='.'&&(in<'0'||in>'9'))
in=getchar();
if(in=='-') {
IsN=true;
num=0;
} else if(in=='.') {
IsD=true;
num=0;
} else num=in-'0';
if(!IsD) {
while(in=getchar(),in>='0'&&in<='9') {
num*=10;
num+=in-'0';
}
}
if(in!='.') {
if(IsN) num=-num;
return ;
} else {
while(in=getchar(),in>='0'&&in<='9') {
num+=Dec*(in-'0');
Dec*=0.1;
}
}
if(IsN) num=-num;
}
inline void read2(double &a,double &b) {
read1(a);
read1(b);
}
inline void read3(double &a,double &b,double &c) {
read1(a);
read1(b);
read1(c);
}
///------------------------------------------------------------------------------------------------------------
int T;
char nouse[35];
int str[50][30];
int main() {
// freopen("in.txt","r",stdin);
while(scanf("%d",&T)!=EOF) {
while(T--)
{
MS0(str);
scanf("%s",nouse);
int len = strlen(nouse);
rep0(i,0,len) str[0][nouse[i]-'a']++;
scanf("%s",nouse);
len = strlen(nouse);
rep0(i,0,len) str[1][nouse[i]-'a']++;
int x;
read1(x);
rep1(i,2,x)
{
rep0(j,0,26)
{
str[i][j] = str[i-1][j]+str[i-2][j];
}
}
rep0(i,0,26) printf("%c:%d\n",i+'a',str[x][i]);
puts("");
}
}
return 0;
}