//巡逻的士兵
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
map<int,int> mp;//注意
int solve(int n)
{
if(mp[n]!=NULL)
return mp[n];
if(n==3)//剩下3个组成一种情况
return mp[n]=1;
if(n<3)//一不小心删多了
return mp[n]=0;
if(n%2==0)
return mp[n]=solve(n/2)+solve(n/2);
else
return mp[n]=solve(n/2)+solve(n/2+1);
}
int main()
{
int n;
scanf("%d",&n);
while(n!=0)
{
printf("%d\n",solve(n));
scanf("%d",&n);
}
return 0;
}
//偷懒的士兵
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
map<int,int> mp;
int solve(int n)
{
if(mp[n]!=NULL)
return mp[n];
if(n==3)//剩下3个组成一种情况
return mp[n]=0;
if(n<3)//一不小心删多了
return mp[n]=n;
if(n%2==0)
return mp[n]=solve(n/2)+solve(n/2);
else
return mp[n]=solve(n/2)+solve(n/2+1);
}
int main()
{
int n;
scanf("%d",&n);
while(n!=0)
{
printf("%d\n",solve(n));
scanf("%d",&n);
}
return 0;
}
//偷懒的士兵2
#include <iostream>
#include <algorithm>
#include <map>
//如果递归的函数只传入一个值的话可以考虑用map存答案加快运算速度 但是如果传好几个值的话开结构体map就有些得不偿失 一般也不会把题目这么出
using namespace std;
int solve(int n,int head,int del)
{
if(n==3)//剩下3个组成一种情况
return 0;
if(n<3)//一不小心删多了
return head;
int a=solve((n+1)/2,head,del*2);//去掉偶数の场合 头不变 长度砍半 距离翻倍
int b=solve(n/2,head+del,del*2);//不是head+1是head+del
//去掉奇数の场合 头是第二个 距离翻倍 长度砍半
if(a>0&&b>0)//特判 0不能参与比较
return min(a,b);
else if(a>0)
return a;
else if(b>0)
return b;
}
int main()
{
int n;
scanf("%d",&n);
while(n!=0)
{
printf("%d\n",solve(n,1,1));
scanf("%d",&n);
}
return 0;
}