腾讯笔试题——用1,1,2,2,4,4,8,8...2^i,2^i拼凑成一个整数n,求问多少种拼凑方法
来源:互联网 发布:excel公开课数据分析 编辑:程序博客网 时间:2024/06/11 23:18
用1,1,2,2,4,4,8,8…2^i,2^i拼凑成一个整数n,求问多少种拼凑方法
话不多说,上代码:
#include<iostream>#include<math.h>#include<time.h>#include<set>using namespace std;int nums[63];//num[i]表示2^i的个数,只有0,1,2三个取值//回溯法int IsOk(long long n,int *nums,int len){ long long sum = 0; for (int i = 0; i < len; i++) sum += nums[i] * pow(2, i); if (sum==n) return 0; else if (sum > n) return -1; else return 1;}void solve(long long n, int index, int *nums, int len,int &count){ if (index >= len) return; for (int i = 0; i <= 2; i++) { nums[index] = i; if (IsOk(n, nums, len) == 0) count++; else if (IsOk(n, nums, len) == 1) solve(n, index + 1, nums, len, count); } nums[index] = 0;//回溯法,要撤回上一步的假设}long long DP(long long n)//使用动态规划方法{ int len = log(n) / log(2) + 1; long long **dp = new long long*[n + 1]; for (long long i = 0; i <= n; i++) { dp[i] = new long long[len]; } for (int i = 0; i < len; i++) for (long long j = 0; j <= n; j++) dp[j][i] = 0; //dp[n][i]表示使用1,1,2,2,4,4,...,2^i可以组合出n的方案数 for (int i = 0; i < len; i++) dp[0][i] = 1; if (n == 1||n==2) return n; dp[1][0] = 1; dp[2][0] = 1; for (int i = 3; i <= n; i++) dp[i][0] = 0; //dp[n][i]=// cout << "len=" << len << endl; for (int i = 1; i < len; i++) for (long long j = 1; j <= n; j++) { for (int m = 0; m <= 2; m++) if (j - pow(2, i)*m >= 0) { dp[j][i] = dp[j][i] + dp[(long long)(j - pow(2, i)*m)][i - 1]; //cout <<"j="<< j << " " << "i=" << i << " " << "m=" << m<<" "<< dp[j][i]<<endl; } } return dp[n][len - 1];}int solve3(long long n){ long long stop = n / 2; long long res = 0; set<int> myset; /* 将硬币分为两份:1,2,4,8,16,.....和1,2,4,8,16.... 组成两个数值为a,b的两个数字,他们的和是a+b=n; a在每一份中只可能有一种组合方式(二进制的思想) */ for (int i = 1; i <= stop; i++) { res = i ^ (n - i); myset.insert(res); } //对于1,2,4,8结果再加1. int len = log(n) / log(2) + 1; if (pow(2, len-1) == n) return myset.size() + 1; return myset.size();}int main(){ for (int i = 0; i < 63; i++) nums[i] = 0; long long n; clock_t start, finish; while (true) { cin >> n; int len = log(n) / log(2) + 1; int count = 0; start = clock(); solve(n, 0, nums, len, count); cout << count << endl; finish = clock(); cout << "回溯法耗费时间为" << (double)(finish - start) / CLOCKS_PER_SEC<<"秒"<<endl; // // start = clock(); long long res = DP(n); cout << res << endl; finish = clock(); cout << "动态规划方法耗费时间为" << (double)(finish - start) / CLOCKS_PER_SEC << "秒" << endl; start = clock(); res = solve3(n); cout << res << endl; finish = clock(); cout << "第三种方法耗费时间为" << (double)(finish - start) / CLOCKS_PER_SEC << "秒" << endl; } return 0; }
输入a,b,A,B,求问:能否经过同时+1或者同时*2变成A,Bint method1(int a,int b,int A,int B){ if(a>A || b>B) return -1; int c = a-b, d = A-B; if(c*d < 0) return -1; if(c==0 && d==0){ // ok }else if(c!=0 && d!=0){ if(d%c!=0) return -1; int e = d/c; if(e&(e-1)!=0) return -1; }else return -1; int res = 0; while(true){ if(A==a) return res; if(A%2==0){ if(A/2>=a){ A>>=1; res++; }else{ res += A-a; return res; } }else{ A-=1; res++; } }}
我的方法:
#include<iostream>using namespace std;bool fun(int a,int A,int b,int B,int &count){ if (a == A&&b==B) return true; if (a > A||b>B) return false; int count1 = 0; int count2 = 0; bool res1 = fun(a + 1, A, b + 1, B, count1); bool res2 = fun(2 * a, A, 2 * b, B, count2); if (res1 || res2) { if (res1&&res2) { count = count1 > count2 ? count2 + 1 : count1 + 1; return true; } if (res1) { count = count1 + 1; return true; } if (res2) { count = count2 + 1; return true; } } else { count = -1; return false; }}int main(){ int a; int A; //cin >> a; //cin >> A; a = 100; A = 408; int b = 1000; int B = 4009; int count = 0; fun(a, A,b,B,count); cout << count << endl;return 0;}
阅读全文
0 0
- 腾讯笔试题——用1,1,2,2,4,4,8,8...2^i,2^i拼凑成一个整数n,求问多少种拼凑方法
- 1/25/50/100美分,多少种可能拼凑成2美元
- 2012腾讯 实习生笔试题目b[i] = a[0]*a[1]*a[2]...*a[N-1]/a[i];
- 2017腾讯校招笔试编程题-拼凑零钱
- main() { int a[3][3],*p,i; p=&a[1][1]; for(i=0;i<4;i++) p[i]=i+1; printf("%d\n",a[1][2]); } 求输出
- 拼凑
- 逆向输出一个数组(头尾交换,a[i]与a[n-i-1]交换,i<=(n-1)/2)
- 已知一个正整数N, 且N = 2i + 2j + … + 2q ,求i, j, ... q的值
- Codeforces Round #353 (Div. 2) E. Trains and Statistic(求d[i][j]的和的最小值(1<=i<=n,i+1<=j<=n))
- 据说是腾讯的面试题:两个数组a[N],b[N],其中A[N]的各个元素值已知,现给b[i]赋值,b[i] = a[0]*a[1]*a[2]...*a[N-1]/a[i];
- 剑指Offer——构建数组B[i]=A[0]*A[1]*....A[i-1]*A[i+1]*A[i+2]*...A[n-1],不能使用除法
- 关于for (i = (n|1)-2; i > 0; i-=2)
- 创新工场笔试题----有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱,求有多少种组合可以组合成n分钱?
- 冒泡排序本质:N个数,需要N-1趟,每趟需要比较N-i次(i是指第i趟)如10个数需要比较9+8+7+6+5+4+3+2+1=45次
- 拼凑纸币、大整数问题
- 从递归计算到线性计算:C(N)=(2/N)*∑(i: 0->N-1) C(i)+N
- 用StringBuffer拼凑Json
- 求N!有多少个0,1,2,…,9
- PC端地图Hybird应用开发(百度地图API+C#+JavaScript)
- 下拉刷新和viewPager左右滑动冲突,下拉刷新和banner滑动布局滑动冲突
- 使用svm进行蚊子识别
- Spring Cloud 学习笔记——入门、特征、配置
- JavaWeb之Ajax
- 腾讯笔试题——用1,1,2,2,4,4,8,8...2^i,2^i拼凑成一个整数n,求问多少种拼凑方法
- Spring MVC HTTP Status 405
- 电子签名
- web前端开发vue笔记学习
- HTML+CSS+jquery 实现环形比例图效果 AngularJS+css实现环形比例图效果
- 获取俩个日期间 工作日天数——搬运工
- Docker简介
- Codeforces Round #434 Polycarp's phone book (字典树)
- ES6对象扩展