PAT甲级 A1103 Integer Factorization (30 分)

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 =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+12, or 112+ 62+ 22 +22 +22 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 i<L and aL>bL 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

主要思路

代码参考了柳神的代码

使用深度优先搜索,首先将v[i]存储数字对应的次方便于后面直接调用。 而后在DFS代码的书写中首先确定跳出的条件,一个是满足题目所说表示的k,p条件,另一个就是当myk的值大于题目给的k时跳出(这个条件在本题中使用无效只是说在刚写代码时应注意判断)
DFS中的myn,myk用于存储当前获得的值的总数以及插入fac的个数,fac用于暂时存储当前路径,fac存储当前的数字总和便于直接获取和最大的路径。在每次进行路径插入的时候为了保证数字时按照从大到小的数字插入的应该对Index进行保存(便于保证下一次插入的数字不比当前的数字大),因而在DFS函数中存放index变量的值。
在实际代码书写过程中注意所有需要使用的变量尽量在函数的参数中防止递归过程中出错(笔者比较菜,递归经常出错)
为了提高运行效率,对于一定无法满足条件的数字进行剔除,也就是必须满足v[i]*(k-myk)>=n-myn条件

代码

#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
int n, k, p, maxfac=0;
vector<int> v ,tans,ans;
void init()
{
	int i = 1;
	v.push_back(0);
	while (pow(i, p) <= n)
	{
		v.push_back(pow(i, p));
		i++;
	}
}
void GetNum(int index,int myn, int myk, int fac)
{
	if (myn >n || myk >k)
		return;
	if (myn == n && myk == k)
	{
		if (fac > maxfac)
		{
			maxfac = fac;
			ans = tans;
		}
		return;
	}
	for (int i = index; i >0; i--)
	{
		if (myn < myk)
			continue;
		if (v[i] + myn <= n&&v[i]*(k-myk)>=n-myn)
		{
			tans.push_back(i);
			GetNum(i, myn + v[i], myk + 1, fac + i);
			tans.pop_back();
		}
	}
	
};
int main()
{
	cin >> n >> k >> p;
	int m;
	m = pow((double)n, 1.0 / p);
	init();
	if (pow(m, p) == n)
		m--;
	GetNum(v.size() - 1, 0, 0, 0);
	if (ans.size() == 0)
		cout << "Impossible";
	else
	{
		cout << n << " = ";
		cout << ans[0] << "^"<<p;
		for (int i = 1; i < ans.size(); i++)
		{
			cout << " + " << ans[i] << "^"<<p;
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值