PAT 甲级 1103 Integer Factorization (DFS)(c++版)(附代码注释)(附题意分析)

1103 Integer Factorization (30 分)

原文链接:http://kakazai.cn/index.php/Kaka/Pat/query/id/193

题目

题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805364711604224

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 = n[1]^P + ... n[K]^P

where n[i] (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+1^2, or 112+62+22+22+2^2, 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 Output2:

Impossible

题意分析

  • 题意

给出n,因子项数k,次方数p。将n分解为k个因子的p次方和。并且要找到因子和最大的方案,若因子和相同,则要找到子序列最大的方案,比如[12, 2, 1]比[11,3,1]更大。

  • 分析

因为n最大值不超过400,因此其可选择的因子是有限的。可以求出所有可选择因子,用深度遍历DFS,逐一遍历所有可能的方案。

知识点与坑点

  • 知识点

1)DFS、最大子序列

  • 坑点

1)一个因子可以被选择多次

一、DFS

算法思路

1 找出所有p次方不大于n的整数,形成序列[m, m-1, m-2,…, 2, 1], m为最大值,该序列包含所有可选做因子的整数。

2 用DFS从m开始,不断往下或重复选择,直到找到满足条件的分解方案。

3 若有多个符合条件的分解方案,选择因子和最大的方案;若方案因子和相同,因为已经从最大因子开始选起,现有方案必然是序列值更大的方案,不必更新。

代码-c++版

#include<cstdio>  
#include<iostream>
#include<vector>
using namespace std;
const int maxn = 401;	//最多有400个因子 
int num[maxn];//存储i的p次方 
int n,k, p;
int maxsum = 0;	//已被选择的因子总和的最大值 
vector<int> temp,path;	//存储符合条件的因子序列 

 /* 计算n的p次方*/
int power(int n, int p) {
  int sum = 1;
  for (int i = 0; i < p; i++) {
    sum *= n;
  }
  return sum;
}
 /* 找出p次方不超过n的所有数,并返回其最大值*/
int fun(int n, int p) {
  int i;
  for (i = 1; i <= n; i++) {
    int temp = power(i, p);
    if (temp > n)return i - 1;
    num[i] = temp;
  }
  return i - 1;
}

 /* DFS:从可能的最大因子开始遍历,直到找到符合条件的分解方案*/
void DFS(int cur, int c,int sum,int facsum) {
//cur为待选择因子;c为已被选择因子数;sum为已被选择因子的p次方总和;
//facsum为已被选择因子的和 

  /* 剪枝 */
  //或和已经超过n;或累计因子数已经超过k;或当前因子已经为0;此时不再选择,结束 
  if (sum > n || c > k || cur < 1)return; 
  
  //符合条件:累加和为n,且累加因子数为k;可以结束。
  if (sum == n && c == k) {
    if (facsum > maxsum) {	//已被选择的因子和更大,则更新 
      maxsum = facsum;
      path = temp;
    }
    return;
  }
    
  //选择当前因子,或重复选择当前因子,或不选择当前因子而选择下一个因子
  temp.push_back(cur);	//选择当前因子cur
  DFS(cur, c + 1, sum + num[cur], facsum + cur); //继续检查当前因子cur是否可再选择 
  temp.pop_back();//分支结束后,弹出该因子cur
  DFS(cur - 1, c, sum, facsum);//不选择cur,检查cur-1是否可选择 
}

int main() {
	
  scanf("%d %d %d", &n, &k, &p);	 
  
  int fac_max = fun(n, p);	//最大的可能因子fac_max
  
 /* 从最大的可能因子开始尝试,用DFS遍历各种分解方案 */  
  DFS(fac_max, 0, 0, 0);
  
   /* 输出 */
  if (maxsum == 0){	//没有符合条件的分解方案 
  	printf("Impossible\n");	 
  }
  else {	//有符合条件的分解方案 
    printf("%d = %d^%d", n, path[0], p);
    for (int i = 1; i < path.size(); i++) {
      printf(" + %d^%d", path[i], p);
    }
  }
  return 0;
}

代码-python版


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值