1103. Integer Factorization (30) -- dfs 回溯
来源:互联网 发布:mac os10.12.6iso 编辑:程序博客网 时间:2024/05/29 16:43
1103 . Integer Factorization (30)
The K-P factorization of a positive integer N is to write N as the sum of the P-th power of K positive integers. You are supposed to write a program to find the K-P factorization of N for any positive integers N, K and P.
Input Specification:
Each input file contains one test case which gives in a line the three positive integers N (<=400), K (<=N) and P (1< P<=7). The numbers in a line are separated by a space.
Output Specification:
For each case, if the solution exists, output in the format:
N = n1^P + … nK^P
where ni (i=1, … K) is the i-th factor. All the factors must be printed in non-increasing order.
Note: the solution may not be unique. For example, the 5-2 factorization of 169 has 9 solutions, such as 122 + 42 + 22 + 22 + 12, or 112 + 62 + 22 + 22 + 22, or more. You must output the one with the maximum sum of the factors. If there is a tie, the largest factor sequence must be chosen – sequence { a1, a2, … aK } is said to be larger than { b1, b2, … bK } if there exists 1<=L<=K such that ai=bi for ibL
If there is no solution, simple output “Impossible”.
Sample Input 1:
169 5 2
Sample Output 1:
169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2
Sample Input 2:
169 167 3
Sample Output 2:
Impossible
http://www.patest.cn/contests/pat-a-practise/1103
// 21分 各种运行超时#include <cstdio>#include <cstdlib>#include <iostream>#include <vector>#include <queue>using namespace std;#define N 20int n , k , p;bool flag ;vector<int> ans ;int numP(int num) // num的p次方{ int sums = num ; for(int i = 1 ; i < p ; i++) { sums *= num ; } return sums;}int sumv(vector<int> vv) // 求和{ int sums = 0 ; for(int i = k-1 ;i >= 0 ; i --) { sums += vv[i]; } return sums;}bool cmp(vector<int> v1,vector<int> v2){ if(sumv(v1) > sumv(v2)) return true; else if (sumv(v1) == sumv(v2)) { for(int i = k-1 ;i >= 0 ; i --) { if(v1[i] > v2[i]) return true; if(v1[i] < v2[i]) return false; } } return false;}vector<int> ansT ;bool dfs(int n , int step){ int i; if(n < 0 || step > k) return false; if(step == k && n == 0) { if(flag == false) { flag = true; for(i = 0 ;i < k;i++) { ans.push_back(ansT[i]); } }else{ if( cmp(ansT,ans) ) { ans.clear(); for(i = 0 ;i < k;i++) { ans.push_back(ansT[i]); } } } return true; }else{ for(i = 1 ;i <= n ; i++) { int num = numP(i); ansT.push_back(i); dfs(n-num , step+1); if((int)ansT.size() > 0 ) ansT.pop_back(); } } return false;}int main(){ //freopen("in.txt","r",stdin); int i; while(scanf("%d%d%d",&n,&k,&p) != EOF) { int tmpn = n ; ans.clear(); ansT.clear(); flag = false; dfs(n,0); if(flag) { printf("%d = %d^%d",tmpn,ans[k-1],p); for(i = k-2;i>=0;i--) { printf(" + %d^%d",ans[i],p); } }else{ printf("Impossible"); } printf("\n"); } return 0 ;}
// 27分代码#include <cstdio>#include <cstdlib>#include <iostream>#include <vector>#include <queue>using namespace std;#define N 20int n , k , p;int ansSum;vector<int> ans ;int numP(int num) // num的p次方{ int sums = num ; for(int i = 1 ; i < p ; i++) { sums *= num ; } return sums;}int sumv(vector<int> vv) // 求最后结果的和{ int sums = 0 ; for(int i = k-1 ;i >= 0 ; i --) { sums += vv[i]; } return sums;}bool cmp(vector<int> v1,vector<int> v2) // 比较结果的大小{ for(int i = k-1 ;i >= 0 ; i --) { if(v1[i] > v2[i]) return true; if(v1[i] < v2[i]) return false; } return false;}vector<int> ansT ;bool dfs(int n , int step){ int i; if(n < 0 || step > k) return false; if(step == k && n != 0) return false; if(step == k && n == 0) { if(ansSum == -1) { ansSum = 0 ; for(i = 0 ;i < k;i++) { ans.push_back(ansT[i]); ansSum += ansT[i]; } }else{ int sumT = sumv(ansT); if( sumT > ansSum ) // 和 大 { ansSum = sumT ; ans.clear(); for(i = 0 ;i < k;i++) { ans.push_back(ansT[i]); } }else if(sumT == ansSum && cmp(ansT,ans)) // 和 相等 { ans.clear(); for(i = 0 ;i < k;i++) { ans.push_back(ansT[i]); } } } return true; }else{ for(i = 1 ;i <= n ; i++) { int num = numP(i); if(num > n) // 这里比n大 则直接 return return false; int len = (int)ansT.size(); if(len > 0 && num < ansT[len-1]) // 跳过该元素 保证后一个元素比前一个元素大于等于 continue; ansT.push_back(i); dfs(n-num , step+1); // dfs 下一个 if((int)ansT.size() > 0) // 回溯 pop出去 ansT.pop_back(); } } return false;}int main(){ //freopen("in.txt","r",stdin); int i; while(scanf("%d%d%d",&n,&k,&p) != EOF) { int tmpn = n ; ans.clear(); ansT.clear(); ansSum = -1 ; dfs(n,0); if(ansSum != -1) { printf("%d = %d^%d",tmpn,ans[k-1],p); for(i = k-2;i>=0;i--) { printf(" + %d^%d",ans[i],p); } }else{ printf("Impossible"); } printf("\n"); } return 0 ;}
// ac代码#include <iostream> #include <cstdio> #include <vector> using namespace std; int num[21]; int maxSum = 0; vector<int> res; vector<int> vec; /**start 表示开始的数k 为个数n 为要求的数sum 为当前已经求得的和*/void dfs(int start, int k, int n, int sum){ if (k == 0){ if (n == 0){ if (sum >= maxSum){ res = vec;//只用记录最后一组答案就好,因为从数学的角度看,这是最佳的 maxSum = sum; } } } else{ if (n > 0){ for (int i = start; i < 21; ++i){ // 显然 n < num[i] 就不满足了 if(n - num[i] < 0) //剪枝,没有这个判断测试点5过不了 break; vec.push_back(i); dfs(i, k - 1, n - num[i], sum + i); vec.pop_back(); // 回溯 直接弹出最后一个数 } } } } int main(void){ int n, k, p; scanf("%d%d%d", &n, &k, &p); // num[i] 表示 i^p 这样就直接不用pow了 for (int i = 1; i < 21; ++i){ num[i] = 1; for (int j = 0; j < p; ++j){ num[i] *= i; } } // dfs(int start, int k, int n, int sum) dfs(1, k, n, 0); if (res.empty()) printf("Impossible\n"); else{ printf("%d = ", n); printf("%d^%d", res[k - 1], p); for (int i = k - 2; i >= 0; --i){ printf(" + "); printf("%d^%d", res[i], p); } printf("\n"); } return 0; }
ac代码学习:http://blog.csdn.net/apie_czx/article/details/48415197
ac20170214
#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <iostream>#include <string>#include <vector>#include <queue>#include <algorithm>#include <sstream>#include <list>#include <stack> #include <map> #include <set> #include <iterator> #include <unordered_map>using namespace std;#define INF 0x7ffffffftypedef long long int LL;const int N = 404;int n, k, p;int maxVal;int pows[N];int maxSum;vector<int> res;vector<int> ans;void dfs(int cur,int ceng,int sumNow,int sum){ if(cur > maxVal || ceng > k || sumNow > n) return; if(sumNow == n && ceng == k) { /*for(int i=0;i<(int)ans.size();i++) cout << ans[i] << " "; cout << endl;*/ if(sum >= maxSum) { maxSum = sum; res = ans; } } for(int i=cur;i<=maxVal;i++) { if(sumNow + pows[i] > n || pows[i] > n) break; ans.push_back(i); dfs(i,ceng + 1, sumNow + pows[i],sum + i); ans.pop_back(); }}int main(){ //freopen("in.txt", "r" ,stdin); while( scanf("%d%d%d", &n, &k, &p) != EOF) { for(int i=1;i<=n;i++) { int powTmp = 1; for(int j=0;j<p;j++) powTmp *= i; int tmp = powTmp; if(tmp <= n) { maxVal = i; pows[i] = tmp; } else break; } res.clear(); ans.clear(); maxSum = -1; dfs(1,0,0,0); if (res.empty()) printf("Impossible\n"); else{ printf("%d = ", n); printf("%d^%d", res[k - 1], p); for (int i = k - 2; i >= 0; --i){ printf(" + "); printf("%d^%d", res[i], p); } printf("\n"); } } return 0;}
- 1103. Integer Factorization (30) -- dfs 回溯
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- 1103. Integer Factorization (30)
- linux kernel Setup.S代码完全注释
- 单元测试
- AppCan开发者资料分享(定期更新)
- Linux的一些重要命令
- java构造函数
- 1103. Integer Factorization (30) -- dfs 回溯
- 用单例模式实现一键退出
- saiku环境搭建
- Android TextView内容居中和控件居中
- 安卓打包
- XCode7真机调试时出现 Could not launch process launch failed: Security
- linux 0.11 内核学习 -- setup.s
- java Timer和TimerTask使用
- test7.15