HihoCoder1873(二进制拆分)

题目:http://hihocoder.com/problemset/problem/1873

题解:采用分治的思想,将大问题逐步分解到小问题:

  

首先,我们可以把问题理解成,我当前站在pos 点,需要m 种方案到达终点,这样我们可以分类讨论:

       <1>m是偶数: 方案数=m/2

                 在pos+1 位置建立一个到pos+3的传送门;在pos+2的地方建立一个到pos+1的传送门,从pos 到pos+3 的方案数是2种;

                 问题就被分解成:我现在站在pos+3点,需要m\2种方案到达终点; ​
      <2>m是奇数的:

                       让 m变成偶数,在pos+1处放置一个到199号点的传送门;

                        然后跳到pos+2号点上,这个问题就变成了:在pos+2点,需要m−1种方案到达终点。

代码:

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 205;
int main()
{
    ll m;
    while(cin>>m){
        int pos = 0,cnt = 0,a[maxn];
        memset(a,-1,sizeof(a));
        if(m==0){
            cout<<"2"<<endl;
            cout<<"1 1"<<endl;
            cout<<"2 1"<<endl;
            continue;
        }
        while(m!=0){
            if(m==1){
                a[pos+1] = 199; 
                a[pos+2] = pos+2;
                cnt += 2;  
                break;
            }else{
                if(m%2==0){
                    a[pos+1] = pos + 3;
                    a[pos+2] = pos + 1; 
                    pos += 3; m /= 2; 
                    cnt += 2;
                }else{
                    a[pos+1] = 199;
                    pos += 2;   m--;  
                    cnt++;
                }
            }
            
            
        }
        cout<<cnt<<endl;
        for(int i=0;i<199;i++){
            if(a[i]==-1) continue;
            cout<<i<<" "<<a[i]<<endl; 
        }
    }
    return 0;
}
View Code

 

posted @ 2019-10-11 17:24  七忆鱼  阅读(205)  评论(0编辑  收藏  举报