CodeForces 217 B Blackboard Fibonacci +暴力

题目链接:

http://codeforces.com/contest/217/problem/B 

B. Blackboard Fibonacci

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Fibonacci numbers are the sequence of integers: f0 = 0, f1 = 1, f2 = 1, f3 = 2, f4 = 3, f5 = 5, ..., fn = fn - 2 + fn - 1. So every next number is the sum of the previous two.

Bajtek has developed a nice way to compute Fibonacci numbers on a blackboard. First, he writes a 0. Then, below it, he writes a 1. Then he performs the following two operations:

  • operation "T": replace the top number with the sum of both numbers;
  • operation "B": replace the bottom number with the sum of both numbers.

If he performs n operations, starting with "T" and then choosing operations alternately (so that the sequence of operations looks like "TBTBTBTB..."), the last number written will be equal to fn + 1.

Unfortunately, Bajtek sometimes makes mistakes and repeats an operation two or more times in a row. For example, if Bajtek wanted to compute f7, then he would want to do n = 6 operations: "TBTBTB". If he instead performs the sequence of operations "TTTBBT", then he will have made 3 mistakes, and he will incorrectly compute that the seventh Fibonacci number is 10. The number of mistakes in the sequence of operations is the number of neighbouring equal operations («TT» or «BB»).

You are given the number n of operations that Bajtek has made in an attempt to compute fn + 1 and the number r that is the result of his computations (that is last written number). Find the minimum possible number of mistakes that Bajtek must have made and any possible sequence of n operations resulting in r with that number of mistakes.

Assume that Bajtek always correctly starts with operation "T".

Input

The first line contains the integers n and r (1 ≤ n, r ≤ 106).

Output

The first line of the output should contain one number — the minimum possible number of mistakes made by Bajtek. The second line should contain n characters, starting with "T", describing one possible sequence of operations with that number of mistakes. Each character must be either "T" or "B".

If the required sequence doesn't exist, output "IMPOSSIBLE" (without quotes).

Examples

input

Copy

6 10

output

Copy

2
TBBTTB

input

Copy

4 5

output

Copy

0
TBTB

input

Copy

2 1

output

Copy

IMPOSSIBLE

 

 题目大意:

给你上下两个数,要你在经过 n 个操作之后得到这个数。操作分为两类:

            1、把上层的数加到下层去,本次得到的数是下层的新数,本次的操作符是 B

            2、把下层的数加到上层去,本次得到的数十上层的新数,本次的操作符是 T

要求你经过n次操作,使上面的数变成 r,定义正确的操作序列TBTB……,

修改n次操作中的某次操作,输出修改次数最少的和最中序列字典序最小的。

如果达不到r输出IMPOSIBLE0

思路:

设上下两个数为t,b

设当前执行的操作序列为‘T', 则t=t+b,t>b;

当前执行的操作序列为‘B',则b=t+b,b>t

我们采用逆推,如果当前的状态为(t,b), t>b,说明执行的为T得来的;

b>t, 说明执行的为B得来的;

即逆推的状态是唯一的,最后的状体为(1,1)

我们知道最后的情况就2*r种,(r,i) 、(i,r)   1<=i<=r

 This is the code:

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<sstream>
#include<stack>
#include<string>
#include<set>
#include<vector>
using namespace std;
#define PI acos(-1.0)
#define EPS 1e-8
#define MOD 1e9+7
#define LL long long
#define ULL unsigned long long     //1844674407370955161
#define INT_INF 0x7f7f7f7f      //2139062143
#define LL_INF 0x7f7f7f7f7f7f7f7f //9187201950435737471
// ios::sync_with_stdio(false);
// 那么cin, 就不能跟C的 scanf,sscanf, getchar, fgets之类的一起使用了。
int n,r;
int res;
char str[1000005];
char s[1000005];
void check(int t,int b)
{
    int len=0;
    while(t!=b && t>=0 && b>=0)
    {
        if(t>b)
        {
            s[len++]='T';
            t-=b;
        }
        else
        {
            s[len++]='B';
            b-=t;
        }
    }
    if(len!=n-1 || t!=1)
          return ;

    s[len]='T';//开头的必定是T
    int k=0;
    for(int i=0;i<len;++i)
        if(s[i]==s[i+1])
            k++;
    if(k<res)
    {
        res=k;
        for(int i=0;i<=len;++i)
            str[i]=s[len-i];
        str[len+1]='\0';
    }
}
int main()
{
    cin>>n>>r;
    res=INT_INF;
    for(int i=1;i<=r;++i)
    {
        check(i,r);
        check(r,i);
    }
    if(res==INT_INF)
        cout<<"IMPOSSIBLE"<<endl;
    else
        cout<<res<<endl<<str<<endl;
    return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值