PAT A1103 Integer Factorization
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
word | meaning |
---|---|
the P-th power of K positive integers | K个正整数的p次方 |
- 输出要求 :
- k个数p次方和为n
- non-increasing order.
- maximum sum
- if there exists 1≤L≤K such that ai=bi for i<L and aL>bL.
- no solution
- 思路 1:
1- 先做预处理,将小于n的所有p次整数存进数组
2- DFS从p次幂小于n的最大整数开始向下搜索(从大到小->满足要求1. 3.),因为可以重复使用元素,每次有两个选择:
1)继续选idex
DFS(idex, num+1, sumS+fac[idex], sum+idex)
2) 试探idex下一个元素(idex-1)
DFS(idex-1, num, sumS, sum)
Ps:之所以num…不更新,是因为idex-1还没push进tmp,如果更新了,下一轮刚好符合要求,进入了if,进而更新ans,得到的结果就错了
3- 当满足要求1时,判断是否比全局max大,大则更新并将tmp复制给结果ans数组
4- 结束后,如果整个DFS过程都没有满足过条件1,即max没有被更新过,输出Impossible,否则格式化输出ans
- code 1:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int n, k, p, len;
vector<int> tmp, ans, fac;
int maxSum = -1;
int pPow(int x){
int res = 1, cnt = p;
while(cnt--){
res *= x;
}
return res;
}
void init(){
int temp = 1, it = 1;
while(temp <= n){ //!!!:Wrong 1:<= 存在it^p刚好==n的情况
fac.push_back(temp);
temp = pPow(it++);
len++;
}
}
void DFS(int idex, int num, int sumS, int sum){
if(num == k && sumS == n){
if(sum > maxSum){
maxSum = sum;
ans = tmp;
}
return;
}
if(num > k || sumS > n) return;
if(idex > 0){
tmp.push_back(idex);
DFS(idex, num+1, sumS + fac[idex], sum + idex);
tmp.pop_back();
DFS(idex-1, num, sumS, sum);
}
}
int main(){
scanf("%d %d %d", &n, &k, &p);
init();
DFS(len-1, 0, 0, 0);
if(maxSum == -1) printf("Impossible");
else{
printf("%d = ", n);
for(int i = 0; i < ans.size(); ++i){
if(i == 0) printf("%d^%d", ans[i], p);
else printf(" + %d^%d", ans[i], p);
}
}
return 0;
}
- T2 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 30;
int Pow[maxn], max_sum = 0;
vector<int> tmp, ans;
void DFS(int id, int num, int sum, int aim, int sum_fac){
if(tmp.size() == num && sum == aim){
if(sum_fac > max_sum){
max_sum = sum_fac;
ans = tmp;
}
return;
}
if(sum < aim && tmp.size() < num){
if(id > 0){
tmp.push_back(id);
DFS(id, num, sum + Pow[id], aim, sum_fac + id);
tmp.pop_back();
DFS(id - 1, num, sum, aim, sum_fac);
}
}
}
int main(){
int n, k, p;
scanf("%d %d %d", &n, &k, &p);
int upper = pow(n, 1.0 / p);
for(int i = 1; i <= upper; ++i){
Pow[i] = pow(i, p);
}
DFS(upper, k, 0, n, 0);
if(ans.size() != 0){
printf("%d = %d^%d", n, ans[0], p);
for(int i = 1; i < ans.size(); ++i){
printf(" + %d^%d", ans[i], p);
}
}else printf("Impossible");
return 0;
}
- T4 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 30;
int P[maxn];
vector<int> tmp, ans;
void DFS(int id, int len, int sump, int aim, int sum_id, int & max_sum_id) //WRONG : max变量未加 &
{
// for(int i = 0; i < tmp.size(); ++i) cout <<tmp[i] << " ";
// cout << sump << " " << sum_id << endl;
if(tmp.size() > len || sump > aim) return;
if(sump == aim && tmp.size() == len)
{
// cout << sum_id << " : YES" <<endl;
if(sum_id > max_sum_id)
{
max_sum_id = sum_id;
ans = tmp;
}
return;
}
if(tmp.size() < len && id > 0)
{
tmp.push_back(id);
DFS(id, len, sump + P[id], aim, sum_id + id, max_sum_id);
tmp.pop_back();
if(id > 1)
{
DFS(id-1, len, sump, aim, sum_id, max_sum_id);
}
}
}
int main()
{
int n, k, p;
scanf("%d %d %d", &n, &k, &p);
int max_factor = pow(n, 1.0 / p), max_sum = 0;
for(int i = 1; i <= max_factor; ++i)
{
P[i] = pow(i, p);
//WRONG 1: 必须用自己的POW, 库函数是double类型进制转换时会发生舍入!!
//补充:这个与编译器有关,PAT上没有问题,codeblock上会出错!
}
DFS(max_factor, k, 0, n, 0, max_sum);
if(ans.size() != 0) printf("%d = ", n);
else printf("Impossible");
for(int i = 0; i < ans.size(); ++i)
{
printf("%d^%d", ans[i], p);
if(i < ans.size()-1) printf(" + ");
}
return 0;
}