CF 134 DIV1 B.Blackboard Fibonacci

来源:互联网 发布:阿里云os电视 编辑:程序博客网 时间:2024/06/12 23:20

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove

果然是暴跌RATE啊。。。

B题当然时没搞出来,YY了通项。

决定用搜索来做,界定上下界优化,结果后期没有心思debug了。

题目是说:两个数,然后有两种操作,将两个数的和替换掉其中一个。依次下去,两种操作轮流,就是FIB数列的构造。给出操作次数N以及第 N项R,问能不能构造出这样的数列,而且要求错误次数最少。也就是相同操作相邻的数量。

对于这个序列,起点是知道的,但是每一步都有两种选择,所以不好确定。

但是反过来,如果给出最后两个数,序列是可以倒推出来的,而且是唯一的。

对于A,B(A>B)那么前一个必然是A-B,B,而且这一步的操作必然是将两者之和替换A-B。

所以做法便是枚举倒数第二项,然后倒推回来,是否刚好N项而且记录错误的次数即可。

有一个优化,便是如果GCD(I,R),即倒数两项并非互质的话,最终总是推出两个数相等,而且大于1,这时候的前一步便是0,d,而且d>0,这是显然不可能的。

而对于A,B这个状态,转移到B,A%B需要的步数也是确定的A/B,错误次数便是A/B-1

枚举结束之后,就是根据保存的最优状态,再倒推一遍,0,1后一步是确定的1,1对于这一步,不管是T还是B操作,结果一样,但是要求错误次数最小,肯定会选择和第一步相反的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<<30using 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\n";}int main(){    int n,r;    while(cin>>n>>r)        if(n==1&&r==1) cout<<"0\nT\n"<<endl;        else slove(n,r);    return 0;}





原创粉丝点击