Problem:
Problem F:
Power Calculus
Starting with
x
and repeatedly multiplying by
x
, we can compute
x
31
with thirty multiplications:
x
2
=
x
×
x
,
x
3
=
x
2
×
x
,
x
4
=
x
3
×
x
, ... ,
x
31
=
x
30
×
x
.
The operation of squaring can appreciably shorten the sequence of multiplications. The following is a way to compute x
31
with eight multiplications:
x
2
=
x
×
x
,
x
3
=
x
2
×
x
,
x
6
=
x
3
×
x
3
,
x
7
=
x
6
×
x
,
x
14
=
x
7
×
x
7
,
x
15
=
x
14
×
x
,
x
30
=
x
15
×
x
15
,
x
31
=
x
30
×
x
.
This is not the shortest sequence of multiplications to compute
x
31
. There are many ways with only seven multiplications. The following is one of them:
x
2
=
x
×
x
,
x
4
=
x
2
×
x
2
,
x
8
=
x
4
×
x
4
,
x
10
=
x
8
×
x
2
,
x
20
=
x
10
×
x
10
,
x
30
=
x
20
×
x
10
,
x
31
=
x
30
×
x
.
There however is no way to compute
x
31
with fewer multiplications. Thus this is one of the
most eficient ways to compute
x
31
only by multiplications.
If division is also available, we can find a shorter sequence of operations. It is possible to
compute
x
31
with six operations (five multiplications and one division):
x
2
=
x
×
x
,
x
4
=
x
2
×
x
2
,
x
8
=
x
4
×
x
4
,
x
16
=
x
8
×
x
8
,
x
32
=
x
16
×
x
16
,
x
31
=
x
32
÷
x
.
This is one of the most eficient ways to compute
x
31
if a division is as fast as a multiplication.
Your mission is to write a program to find the least number of operations to compute
x
n
by multiplication and division starting with
x
for the given positive integer
n
. Products and
quotients appearing in the sequence of operations should be
x
to a positive integer's power. In
other words,
x
-3
, for example, should never appear.
Input
The input is a sequence of one or more lines each containing a single integer
n
.
n
is positive and
less than or equal to 1000. The end of the input is indicated by a zero.
Output
Your program should print the least total number of multiplications and divisions required to
compute
x
n
starting with
x
for the integer
n
. The numbers should be written each in a separate
line without any superfluous characters such as leading or trailing spaces.
Sample Input
1
31
70
91
473
512
811
953
0
Output for the Sample Input
0
6
8
9
11
9
13
12

Submitted solutions:

code_snippet: /*
 *Author:       Zhaofa Fang
 *Created time: 2013-09-09-16.49 星期一
 */
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;

typedef long long ll;
typedef pair<int,int> PII;
#define DEBUG(x) cout<< #x << ':' << x << endl
#define FOR(i,s,t) for(int i = (s);i <= (t);i++)
#define FORD(i,s,t) for(int i = (s);i >= (t);i--)
#define REP(i,n) for(int i=0;i<(n);i++)
#define REPD(i,n) for(int i=(n-1);i>=0;i--)
#define PII pair<int,int>
#define PB push_back
#define ft first
#define sd second
#define lowbit(x) (x&(-x))
#define INF (1<<30)
#define eps (1e-8)

int n,ans;
int A[500];
bool vist[3000];
int step[3000];

void dfs(int cur,int tot){
    if(tot >= ans || cur > 2*n || (~step[cur]&&tot>step[cur]))return;
    if(cur == n){
        ans = min(ans,tot);
        return;
    }
    if(step[cur] == -1)step[cur] = tot;
    else if(step[cur] > tot)step[cur] = tot;
   // printf("%d %d %d\n",cur,tot,ans);
    REPD(i,tot+1){
        int xx = cur + A[i];
        if(xx > 2*n || vist[xx])continue;
        vist[xx] = 1;A[tot+1] = xx;
        dfs(xx,tot+1);
        vist[xx] = 0;
    }
    REPD(i,tot+1){
        int xx = cur - A[i];
        if(xx <=0 || vist[xx])continue;
        vist[xx] = 1;A[tot+1] = xx;
        dfs(xx,tot+1);
        vist[xx] = 0;
    }
}
int main(){
    //freopen("in","r",stdin);
    //freopen("out","w",stdout);
   // FOR(i,1,1000)
    while(~scanf("%d",&n),n)
    {
        memset(step,-1,sizeof(step));
      //  n = i;
        ans = 14;//BFS();//DEBUG(ans);
        A[0] = 1;
        dfs(1,0);
        printf("%d\n",ans);
      //  if(n%40==0)puts("");
    }
    return 0;
}
accuracy: 1
time_ms: 1060
memory_kb: 3264
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int N = 106;
int x[N], n, m;

bool dfs(int k, int s) {
    if (k == n) return true;
    if (s == m) return false;
    if (k < n && (k * (1 << (m - s)) < n)) return false;

    x[s] = k;
    for (int i = 0; i <= s; ++i) {
        int new_val1 = k + x[i];
        if (new_val1 <= 10000) { // Prevent overflow
            bool found = false;
            for (int j = 0; j <= s; ++j) {
                if (x[j] == new_val1) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                if (dfs(new_val1, s + 1)) return true;
            }
        }

        int new_val2 = abs(k - x[i]);
        if (new_val2 > 0 && new_val2 <= 10000) {
            bool found = false;
            for (int j = 0; j <= s; ++j) {
                if (x[j] == new_val2) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                if (dfs(new_val2, s + 1)) return true;
            }
        }
    }
    return false;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    while (cin >> n && n) {
        if (n == 1) {
            cout << "0\n";
            continue;
        }
        m = 0;
        while (!dfs(1, 0)) ++m;
        cout << m << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 360
memory_kb: 3368
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define _for(i, a, b) for (int i = (a); i < (int)(b); ++i)
const int maxans = 13;  // 试验出来的结果
int N, A[maxans + 1];
bool dfs(int d, int maxd) {
  if (A[d] == N) return true;
  if (d == maxd) return false;
  int maxv = *max_element(A, A + d + 1);
  if ((maxv << (maxd - d)) < N) return false;  // 剪枝
  for (int i = d; i >= 0; i--) {  // 总是使用最后一个值和前面的某个i值做加减
    A[d + 1] = A[d] + A[i];  // 无法证明，也没找到反例
    if (dfs(d + 1, maxd)) return true;
    A[d + 1] = A[d] - A[i];  // 减去前面的某个值生成一个新的次数
    if (dfs(d + 1, maxd)) return true;
  }
  return false;
}
int solve(int N) {
  if (N == 1) return 0;
  A[0] = 1;
  _for(maxd, 1, maxans) if (dfs(0, maxd)) return maxd;
  return maxans;
}
int main() {
  while (scanf("%d", &N) == 1 && N) printf("%d\n", solve(N));
  return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 3484
final_rank: 12

code_snippet: #include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <vector>

using namespace std;
using ll = long long;

// 現在の演算回数 c と演算履歴 history から x^target を upper_limit 回の演算以内で計算できるならば true を返す。そうでなければ false を返す。
bool Dfs(const int c, vector<int>& history, const int target, int& upper_limit) {
	if (history[c] == target) return true;
	if (c == upper_limit) return false;

	int max = *max_element(history.begin(), history.begin() + c + 1);
	if ((max << (upper_limit - c)) < target) return false;

	for (int i = 0; i <= c; i++) {
		if (i != c and history[i] == history[c]) return false;

		history[c + 1] = history[i] + history[c];
		if (Dfs(c + 1, history, target, upper_limit)) return true;

		if (history[i] < history[c]) {
			history[c + 1] = history[c] - history[i];
			if (Dfs(c + 1, history, target, upper_limit)) return true;
		}
	}
	return false;
}

int Solve(const int n) {
	// 反復深化深さ優先探索
	for (int upper_limit = 0;; upper_limit++) {
		vector<int> history(upper_limit + 1, {1}); // i 回目の演算で x^(history[i]) が得られたという履歴
		if (Dfs(0, history, n, upper_limit)) return upper_limit;
	}
}

int main(void) {
	while (true) {
		int n;
		cin >> n;
		if (n == 0) break;
		cout << Solve(n) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 370
memory_kb: 3124
final_rank: 9

code_snippet: #include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <vector>

#define INF (17)

using namespace std;
using ll = long long;

// 現在の演算回数 c と演算履歴 history から x^target を upper_limit 回の演算以内で計算できるならば true を返す。そうでなければ false を返す。
bool Dfs(const int c, array<int, INF>& history, const int target, int& upper_limit) {
	if (history[c] == target) return true;
	if (c == upper_limit) return false;

	int max = *max_element(history.begin(), history.begin() + c + 1);
	if ((max << (upper_limit - c)) < target) return false;

	for (int i = 0; i <= c; i++) {
		if (i != c and history[i] == history[c]) return false;

		history[c + 1] = history[i] + history[c];
		if (Dfs(c + 1, history, target, upper_limit)) return true;

		if (history[i] < history[c]) {
			history[c + 1] = history[c] - history[i];
			if (Dfs(c + 1, history, target, upper_limit)) return true;
		}
	}
	return false;
}

int Solve(const int n) {
	// 反復深化深さ優先探索
	for (int upper_limit = 0;; upper_limit++) {
		array<int, INF> history{1}; // i 回目の演算で x^(history[i]) が得られたという履歴
		if (Dfs(0, history, n, upper_limit)) return upper_limit;
	}
}

int main(void) {
	while (true) {
		int n;
		cin >> n;
		if (n == 0) break;
		cout << Solve(n) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 3432
final_rank: 13

code_snippet: #include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <vector>

#define INF (17)

using namespace std;
using ll = long long;

bool ChMinZP(int& a, const int b) {
	if ((a < 0 or a > b) and b >= 0) {
		a = b;
		return true;
	}
	return false;
}

int CalcUpperLimit(int n) {
	int popcount = 0, numof_digits = 0;
	for (int i = 1; n != 0; i++, n >>= 1) {
		if (n & 1) {
			popcount++;
			numof_digits = i;
		}
	}
	int upper_limit = numof_digits + popcount - 2;
	return upper_limit;
}

// 現在の演算回数 c と演算履歴 history から x^target を upper_limit 回の演算以内で計算できるならば、その演算回数を返す。そうでなければ -1 を返す。
bool Dfs(const int c, array<int, INF>& history, const int target, int& upper_limit) {
	if (history[c] == target) return true;
	if (c == upper_limit) return false;

	int max = *max_element(history.begin(), history.begin() + c + 1);
	if ((max << (upper_limit - c)) < target) return false;

	for (int i = 0; i <= c; i++) {
		if (i != c and history[i] == history[c]) return false;

		history[c + 1] = history[i] + history[c];
		if (Dfs(c + 1, history, target, upper_limit)) return true;

		if (history[i] < history[c]) {
			history[c + 1] = history[c] - history[i];
			if (Dfs(c + 1, history, target, upper_limit)) return true;
		}
	}
	return false;
}

int Solve(const int n) {
	// 反復深化深さ優先探索
	for (int upper_limit = 0;; upper_limit++) {
		array<int, INF> history{1}; // i 回目の演算で x^(history[i]) が得られたという履歴
		if (Dfs(0, history, n, upper_limit)) return upper_limit;
	}
}

int main(void) {
	while (true) {
		int n;
		cin >> n;
		if (n == 0) break;
		cout << Solve(n) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 3440
final_rank: 17

code_snippet: #include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <vector>

#define INF (17)

using namespace std;
using ll = long long;

ll counter = 0;

bool ChMinZP(int& a, const int b) {
	if ((a < 0 or a > b) and b >= 0) {
		a = b;
		return true;
	}
	return false;
}

int CalcUpperLimit(int n) {
	int popcount = 0, numof_digits = 0;
	for (int i = 1; n != 0; i++, n >>= 1) {
		if (n & 1) {
			popcount++;
			numof_digits = i;
		}
	}
	int upper_limit = numof_digits + popcount - 2;
	return upper_limit;
}

// // 現在の演算回数 c と演算履歴 history から x^target を upper_limit 回の演算以内で計算できるならば、その演算回数を返す。そうでなければ -1 を返す。
// int Dfs(const int c, array<int, INF>& history, const int target, int& upper_limit) {
// 	counter++;
// 	if (history[c] == target) return c;
// 	if (c == upper_limit) return -1;

// 	int max = *max_element(history.begin(), history.begin() + c + 1);
// 	if ((max << (upper_limit - c)) < target) return -1;

// 	int ans = -1;
// 	for (int i = 0; i <= c; i++) {
// 		if (i != c and history[i] == history[c]) return -1;

// 		history[c + 1] = history[i] + history[c];
// 		if (ChMinZP(ans, Dfs(c + 1, history, target, upper_limit))) upper_limit = ans;

// 		if (history[i] < history[c]) {
// 			history[c + 1] = history[c] - history[i];
// 			if (ChMinZP(ans, Dfs(c + 1, history, target, upper_limit))) upper_limit = ans;
// 		}
// 	}
// 	return ans;
// }

// 現在の演算回数 c と演算履歴 history から x^target を upper_limit 回の演算以内で計算できるならば、その演算回数を返す。そうでなければ -1 を返す。
bool Dfs(const int c, array<int, INF>& history, const int target, int& upper_limit) {
	counter++;
	if (history[c] == target) return true;
	if (c == upper_limit) return false;

	int max = *max_element(history.begin(), history.begin() + c + 1);
	if ((max << (upper_limit - c)) < target) return false;

	for (int i = 0; i <= c; i++) {
		if (i != c and history[i] == history[c]) return false;

		history[c + 1] = history[i] + history[c];
		if (Dfs(c + 1, history, target, upper_limit)) return true;

		if (history[i] < history[c]) {
			history[c + 1] = history[c] - history[i];
			if (Dfs(c + 1, history, target, upper_limit)) return true;
		}
	}
	return false;
}

int Solve(const int n) {
	// array<int, INF> history{1};			 // i 回目の演算で x^(history[i]) が得られたという履歴
	// int upper_limit = CalcUpperLimit(n); // 求める演算回数の上限
	// int ans = Dfs(0, history, n, upper_limit);
	// return ans;

	for (int ul = 0;; ul++) {
		array<int, INF> history{1}; // i 回目の演算で x^(history[i]) が得られたという履歴
		if (Dfs(0, history, n, ul)) return ul;
	}
}

int main(void) {
	while (true) {
		int n;
		cin >> n;
		if (n == 0) break;
		cout << Solve(n) << endl;
		// cout << counter << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 3056
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;

int d,n;
int a[1001];
bool dfs(int x){
	if(x==d)return a[x-1]==n;
	for(int i=x-1;i>=0;i--){
		int t=a[x-1]+a[i];
		if(t>n)continue;
		a[x]=t;
		for(int i=x+1;i<=d;i++){
			t*=2;
		}
		if(t<n) return 0;
		if(dfs(x+1))return 1;
	}
	for(int i=0;i<=x-1;i++){
		int t=a[x-1]-a[i];
		if(t<=0)continue;
		a[x]=t;
//		for(int i=x+1;i<=d;i++){
//			t*=2;
//		}
//		if(t<n) return 0;
		if(dfs(x+1))return 1;
	}
	return 0;
}
int main(){
	a[0]=1;
	while(cin>>n,n){
		d=1;
		while(!dfs(1))d++;
		cout<<d-1<<endl;
//		for(int i=0;i<d;i++){
//			cout<<a[i]<<" ";
//		}cout<<endl;
	}
	
}
accuracy: 1
time_ms: 580
memory_kb: 3208
final_rank: 16

code_snippet: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <queue>
#include <map>
#include <set>

#define FRER() freopen("in.txt", "r", stdin);
#define INF 0x3f3f3f3f

using namespace std;

const int maxn = 10000 + 5;

int num[maxn], vis[maxn], temp[50], maxd, n;

bool dfs(int, int);

int main()
{
    //FRER()
    ios::sync_with_stdio(0);
    cin.tie(0);

    temp[0] = 1;
    for(int i = 1; i < 32; ++ i)
        temp[i] = temp[i - 1] << 1;
    while(cin >> n && n) {
        memset(vis, 0, sizeof(vis));
        for(maxd = 0; ; ++maxd)
            if(dfs(0, 1)) break;
        cout << maxd << endl;
    }
    return 0;
}

bool dfs(int cur, int s) {
    if(cur == maxd && s == n) return true;
    if(cur > maxd) return false;
    if(s * temp[maxd - cur] < n) return false;
    num[cur] = s;
    vis[s] = 1;
    for(int i = 0; i <= cur; ++i) {
        int u = num[i] + s;
        if(!vis[u]) {
            vis[u] = 1;
            if(dfs(cur + 1, u)) return true;
            vis[u] = 0;
        }
        u = abs(num[i] - s);
        if(!vis[u]) {
            vis[u] = 1;
            if(dfs(cur + 1, u)) return true;
            vis[u] = 0;
        }
    }
    vis[s] = 0;
    return false;
}
accuracy: 1
time_ms: 320
memory_kb: 3424
final_rank: 15

code_snippet: #include<cstdio>
#include<algorithm>
using namespace std;
int cnt[/*11*/45/*14*/],n;
int maxd;
bool dfs(int dep,int x)
{
	if (cnt[dep]==n)	return true;
	if (dep>=maxd)	return false;
	x=max(x,cnt[dep]);
    if(x*(1<<(maxd-dep))<n)
    	return false;
    for (int i=0;i<=dep;i++)
    {
    	cnt[dep+1]=cnt[dep]+cnt[i];
    	if (dfs(dep+1,x))	return true;
    	if (cnt[dep]>cnt[i])	cnt[dep+1]=cnt[dep]-cnt[i];
    	else	cnt[dep+1]=cnt[i]-cnt[dep];
    	if (dfs(dep+1,x))	return true;
	}
	return false;
}
int solve()
{
	cnt[0]=1;
	scanf("%d",&n);
	if (n==0)	return 1;
	if (n==1){
		printf("%d\n",0);
		return 0;
	}
	maxd=0;
	while (!dfs(0,0))	maxd++;
	printf("%d\n",maxd);
	return 0;
}
int main()
{
	while (!solve())
	{
		continue;
	}
}
accuracy: 1
time_ms: 210
memory_kb: 2804
final_rank: 4

code_snippet: #include<iostream>
using namespace std;
int n,a[16];
bool dfs(int deep,int dep,int mx){
	if(a[dep-1]==n)return 1;
	if(dep>deep)return 0;
	if(mx*(1<<(deep-dep)+1)<n)return 0;
	for(int i=0;i<dep;i++){
		a[dep]=a[i]+a[dep-1];
		if(dfs(deep,dep+1,max(mx,a[dep])))return 1;
		a[dep]=a[i]-a[dep-1];
		if(a[dep]<0)a[dep]=-a[dep];
		if(dfs(deep,dep+1,max(mx,a[dep])))return 1;
	}
	return 0;
}
int main(){
	a[0]=1;
	while(cin>>n&&n){
		for(int i=0;i<=15;i++){
			if(dfs(i,1,1)){
				cout<<i<<endl;
				break;
			}
		}
	}
	return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 3364
final_rank: 11

code_snippet: #include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m[20],dep;
bool dfs(int s)
{
	if(s>dep)return 0;
	if(m[s]==n)return 1;
	if(m[s]<<(dep-s)<n)return 0;
	for(int i=0;i<=s;i++)
	{
		m[s+1]=m[s]+m[i];
		if(dfs(s+1))return 1;
		m[s+1]=abs(m[s]-m[i]);
		if(dfs(s+1))return 1;
		
	}
	return 0;
}
int main()
{
	while(scanf("%d",&n)&&n)
	{
		for(dep=0;;dep++)
		{
			m[0]=1;
			if(dfs(0))break;
		}
		printf("%d\n",dep);
	}
	return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 2764
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
const int N=101;
int n,a[101],max_dep;
bool dfs(int t,int x)
{
	if(t>max_dep || x<=0 || (x<<(max_dep-t))<n) return 0;
	if(x==n || x<<(max_dep-t)==n ) return 1;
	a[t]=x;
	for(int i=0;i<=t;i++)
	{
		if(dfs(t+1,x+a[i])) return 1;
		if(dfs(t+1,x-a[i])) return 1; 
	}
	return 0;
}
int main()
{ 
	while(cin>>n && n)
	{
		max_dep=0;
		while(dfs(0,1)==0)
		{
			max_dep++;
		}
		cout<<max_dep<<endl;
	}
}
accuracy: 1
time_ms: 190
memory_kb: 3360
final_rank: 10

code_snippet: #pragma GCC optimize("O3,unroll-loops")
#include <algorithm>
#include <cstdio>
int n, lim, a[21];
bool Dfs(int x, int d) {
  if (d == lim) return x == n;
  a[d] = x;
  int max = *std::max_element(a, a + d + 1);
  if ((max << (lim - d)) < n) return false;
  for (int i = 0; i <= d; i++) {
    if (Dfs(x + a[i], d + 1)) return true;
    if (x > a[i] && Dfs(x - a[i], d + 1)) return true;
  }
  return false;
}
int main(int argc, char const *argv[]) {
  while (std::scanf("%d", &n) == 1) {
    if (n == 0) break;
    for (lim = 0;; lim++)
      if (Dfs(1, 0)) {
        std::printf("%d\n", lim);
        break;
      }
  }
  return 0;
}
accuracy: 1
time_ms: 340
memory_kb: 2908
final_rank: 7

code_snippet: // 先预处理好 n = 1...1000 的答案，在询问时一次输出 
// 剪枝：append一个数v时, 如果v的深度大于它的最浅深度就不优. 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <utility>
#include <queue>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldouble;
const int LEN = 100000;

struct fastio {
  int it, len;
  char s[LEN + 5];
  fastio() {
    it = len = 0;
  }
  char get() {
    if (it < len) return s[it++];
    it = 0, len = fread(s, 1, LEN, stdin);
    return len ? s[it++] : EOF;
  }
  bool notend() {
    char c;
    for (c = get(); c == ' ' || c == '\n' || c == '\r'; c = get());
    if (it) it--;
    return c != EOF;
  }
  void put(char c) {
    if (it == LEN) fwrite(s,1,LEN,stdout), it = 0;
    s[it++] = c;
  }
  void flush() {
    fwrite(s, 1, it, stdout);
    it = 0;
  }
}buff, bufo;
inline int getint() {
  char c; int res = 0, sig = 1;
  for (c = buff.get(); c < '0' || c > '9'; c = buff.get()) if(c == '-') sig = -1;
  for (; c >= '0' && c <= '9'; c = buff.get()) res = res * 10 + (c - '0');
  return sig * res;
}
inline ll getll() {
  char c; ll res = 0, sig = 1;
  for (c = buff.get(); c < '0' || c > '9'; c = buff.get()) if (c == '-') sig = -1;
  for (; c >= '0' && c <= '9'; c = buff.get()) res = res * 10 + (c - '0');
  return sig * res;
}
inline void putint(int x, char suf) {
  if (!x) bufo.put('0');
  else {
    if (x < 0) bufo.put('-'), x = -x;
    int k = 0; char s[15];
    while (x) {
      s[++k] = x % 10 + '0';
      x /= 10;
    }
    for (; k; k--) bufo.put(s[k]);
  }
  bufo.put(suf);
}
inline void putll(ll x, char suf) {
  if (!x) bufo.put('0');
  else {
    if (x < 0) bufo.put('-'), x = -x;
    int k = 0; char s[25];
    while (x) {
      s[++k] = x % 10 + '0';
      x /= 10;
    }
    for (; k; k--) bufo.put(s[k]);
  }
  bufo.put(suf);
}
inline char get_char() {
  char c;
  for (c = buff.get(); c == ' ' || c == '\n' || c == '\r'; c = buff.get());
  return c;
}
template<class T> bool chmin(T &x, T y) {
  return x > y ? (x = y, true) : false;
}
template<class T> bool chmax(T &x, T y) {
  return x < y ? (x = y, true) : false;
}

const int LIM = 1 << 13;
const int inf = 0x3f3f3f3f;
int ans[(1 << 13) + 5]; // minimum depth.
vector<int> have;

void iddfs(int maxDep) {
  if ((int)have.size() == maxDep + 1) return;
  vector<int> nxt;
  for (auto i : have) {
    int perhaps = i << 1;
    if (perhaps <= LIM && ans[perhaps] >= (int)have.size()) // 剪枝 
      nxt.push_back(perhaps);
  }
  for (int i = 0; i < (int)have.size(); i++) {
    for (int j = i + 1; j < (int)have.size(); j++) {
      int perhaps = have[i] + have[j];
      if (perhaps <= LIM && ans[perhaps] >= (int)have.size())
        nxt.push_back(perhaps);
      perhaps = abs(have[i] - have[j]);
      if (perhaps <= LIM && ans[perhaps] >= (int)have.size())
        nxt.push_back(perhaps);
    }
  }
  sort(nxt.begin(), nxt.end());
  nxt.erase(unique(nxt.begin(), nxt.end()), nxt.end()); // 排除等效冗余
  for (auto i : nxt) {
    ans[i] = have.size();
    have.push_back(i); 
    iddfs(maxDep);
    have.pop_back();
  }
}

int main() {
  memset(ans, 0x3f, sizeof(ans));
  have.push_back(1);
  ans[1] = 0;
  for (int i = 1; i <= 13; i++) iddfs(i);
  int x;
  while (x = getint()) putint(ans[x], '\n'); 
  bufo.flush();
  return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 3044
final_rank: 6

code_snippet: #include <cstdio>
using namespace std;

int ans, n, a[105];

bool dfs(int dep, int sum)
{
    int b = sum << (ans - dep);
    if (dep > ans || b < n || sum <= 0)
        return false;
    a[dep] = sum;
    if (sum == n || b == n)
        return true;
    for (int i = 0; i <= dep; ++i)
        if (dfs(dep + 1, sum + a[i]) || dfs(dep + 1, sum - a[i]))
            return true;
    return false;
}

int main()
{
    while (true)
    {
        scanf("%d", &n);
        if (n == 0)
            break;
        for (ans = 0;; ans++)
        {
            if (dfs(0, 1))
            {
                printf("%d\n", ans);
                break;
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 2620
final_rank: 3

code_snippet: #include <cstdio>
using namespace std;

int ans, n, a[105];

bool dfs(int dep, int sum)
{
    if (dep > ans || sum << (ans - dep) < n || sum <= 0)
        return false;
    a[dep] = sum;
    if (sum == n || sum << (ans - dep) == n)
        return true;
    for (int i = 0; i <= dep; ++i)
        if (dfs(dep + 1, sum + a[i]) || dfs(dep + 1, sum - a[i]))
            return true;
    return false;
}

int main()
{
    while (true)
    {
        scanf("%d", &n);
        if (n == 0)
            break;
        for (ans = 0;; ans++)
        {
            if (dfs(0, 1))
            {
                printf("%d\n", ans);
                break;
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 2576
final_rank: 1

code_snippet: #include <cstdio>
using namespace std;

int ans, n, a[105];

bool dfs(int dep, int sum)
{
    if (dep > ans || sum << (ans - dep) < n || sum <= 0)
        return false;
    a[dep] = sum;
    if (sum == n || sum << (ans - dep) == n)
        return true;
    for (int i = 0; i <= dep; ++i)
        if (dfs(dep + 1, sum + a[i]) || dfs(dep + 1, sum - a[i]))
            return true;
    return false;
}

int main()
{
    while (true)
    {
        scanf("%d", &n);
        if (n == 0)
            break;
        for (ans = 0;; ++ans)
        {
            if (dfs(0, 1))
            {
                printf("%d\n", ans);
                break;
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 2600
final_rank: 2