hdu 1708 Fibonacci String

题目链接:点这里

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zuhiul

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值