CF 134 DIV1 B.Blackboard Fibonacci
転載は出典を明記してください、ありがとうございます http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
やっぱり暴落RATEですね...
B問題はもちろんできなかったが,YYはパスした.
検索で行い,上下境界最適化を定義することにしたが,後期はdebugに気を取らなかった.
2つの数、それから2つの操作があって、2つの数の和をその中の1つに置き換えます.順番に下りていくと、2つの操作が交代してFIB数列の構造になります.操作回数NおよびN番目のRを与え,このような数列を構築できるかどうかを尋ね,エラー回数を最小限に抑える.つまり、同じ操作で隣接する数です.
このシーケンスについては、起点は知っていますが、ステップごとに2つの選択があるので、確定しにくいです.
しかし逆に,最後の2つの数を与えると,シーケンスは逆に押し出すことができ,唯一である.
Aに対して、B(A>B)では、前は必ずA−B、Bであり、このステップの動作は必ず両者の和をA−Bに置き換える.
だから、最後から2番目の項目を列挙して、逆さまに押して、ちょうどN項目かどうか、そして間違った回数を記録すればいいのです.
1つの最適化は,GCD(I,R),すなわち逆数の2つが互いに質を持たない場合,最終的には常に2つの数が等しく,1より大きく,このときの前のステップは0,d,d>0であり,これは明らかに不可能である.
一方,A,Bという状態では,Bに移行し,A%Bに必要なステップ数も決定されたA/Bであり,エラー回数はA/B-1である.
列挙が終了すると、保存された最適状態に基づいて、もう一度逆算し、0、1の後のステップが確定した1、1このステップについては、TでもBでも結果は同じですが、エラー回数が最小であることが要求され、第1のステップとは逆のB操作が選択されるに違いありません.
やっぱり暴落RATEですね...
B問題はもちろんできなかったが,YYはパスした.
検索で行い,上下境界最適化を定義することにしたが,後期はdebugに気を取らなかった.
2つの数、それから2つの操作があって、2つの数の和をその中の1つに置き換えます.順番に下りていくと、2つの操作が交代してFIB数列の構造になります.操作回数NおよびN番目のRを与え,このような数列を構築できるかどうかを尋ね,エラー回数を最小限に抑える.つまり、同じ操作で隣接する数です.
このシーケンスについては、起点は知っていますが、ステップごとに2つの選択があるので、確定しにくいです.
しかし逆に,最後の2つの数を与えると,シーケンスは逆に押し出すことができ,唯一である.
Aに対して、B(A>B)では、前は必ずA−B、Bであり、このステップの動作は必ず両者の和をA−Bに置き換える.
だから、最後から2番目の項目を列挙して、逆さまに押して、ちょうどN項目かどうか、そして間違った回数を記録すればいいのです.
1つの最適化は,GCD(I,R),すなわち逆数の2つが互いに質を持たない場合,最終的には常に2つの数が等しく,1より大きく,このときの前のステップは0,d,d>0であり,これは明らかに不可能である.
一方,A,Bという状態では,Bに移行し,A%Bに必要なステップ数も決定されたA/Bであり,エラー回数はA/B-1である.
列挙が終了すると、保存された最適状態に基づいて、もう一度逆算し、0、1の後のステップが確定した1、1このステップについては、TでもBでも結果は同じですが、エラー回数が最小であることが要求され、第1のステップとは逆のB操作が選択されるに違いありません.
#include<iostream>
#include<fstream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<sstream>
#include<cassert>
#define LL long long
#define eps 1e-7
#define inf 1<<30
using namespace std;
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
void calc(int a,int b,int &mis,int &step){
if(b==1){mis+=a-1;step+=a;return;}
step+=a/b; //
mis+=a/b-1; // 1
calc(b,a%b,mis,step);
}
void get_ope(int a,int b,string &s){
// , T, 1,1, T, B,
// , B
if(b==1){for(int i=1;i<a;i++) s+='B'; return;}
get_ope(b,a%b,s);
// ,
char ch=s[s.size()-1]=='T'?'B':'T';
for(int i=0;i<a/b;i++) s+=ch;
}
void slove(int n,int r){
int mistake=inf; //
int num; //
for(int i=r-1;i>=1;i--){
if(gcd(i,r)==1){
int mis=0;
int step=0;
calc(r,i,mis,step);
if(step==n&&mis<mistake){num=i;mistake=mis;}
}
}
if(mistake!=inf){
cout<<mistake-1<<endl;
string s="T";
get_ope(r,num,s);
cout<<s<<endl;
}
else
cout<<"IMPOSSIBLE
";
}
int main(){
int n,r;
while(cin>>n>>r)
if(n==1&&r==1) cout<<"0
T
"<<endl;
else slove(n,r);
return 0;
}