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;}
0 0
原创粉丝点击