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种方案到达终点。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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;
}