切纸片问题。
因为最高只有6位数,直接深搜。复杂度为O(2^6)
预先处理一下,将纸片上各个位置的数取出来,如12346用一个数组保存下来就是1 、2、 3、 4、 6。对于每个顿号处有切和不切两种选法,再用一个数组保存每个位置到底是切还是不切。按照此思路深搜下去就可以得到最后的答案了。
#include <iostream>
#include <cstring>
using namespace std;
const int MAX_LENTH = 6;
int sum[65];
int total_sum_number;
int numbers[MAX_LENTH];
int ans_paper[MAX_LENTH];
int final_ans[MAX_LENTH], final_pieces;
char cut[MAX_LENTH]; //at the certain place cut or not cur;
int target_number, paper_number, digits_number, pieces_number, ans_number,closest_number;
void dfs(int cur) {
if (cur == digits_number) {
int the_digit, current_point = 0;
for (int i = 0; i <pieces_number;i++) {
for (the_digit = numbers[current_point];cut[current_point+1] == 'n' ;current_point++) {
the_digit = the_digit * 10 + numbers[current_point+1];
}
ans_paper[i] = the_digit;
current_point++;
}
int temp_sum = 0;
for (int i = 0;i < pieces_number;i++) {
temp_sum += ans_paper[i];
}
if (temp_sum > target_number)
return ;
else {
int temp_close = target_number - temp_sum;
sum[total_sum_number++] = temp_close;
if (temp_close <= closest_number) {
closest_number = temp_close;
memcpy(final_ans,ans_paper,sizeof(final_ans));
final_pieces = pieces_number;
return ;
}
}
} else {
cut[cur] = 'y';
pieces_number++;
dfs(cur+1);
pieces_number--;
cut[cur] = 'n';
dfs(cur+1);
}
}
int main()
{
int temp_min;
while (cin >> target_number >> paper_number) {
if (!target_number && !paper_number) {
break;
}
digits_number = 0;
for (int j = paper_number ;j > 0;digits_number++) {
j /= 10;
}
for (int i = digits_number-1, j = paper_number; i >= 0;i--) {
numbers[i] = j % 10;
j /= 10;
}
temp_min = 0;
for (int i = 0;i < digits_number;i++) {
temp_min += numbers[i];
}
if (temp_min > target_number) {
cout << "error" << endl;;
continue;
}
closest_number = 100000;
pieces_number = 1;
memset(cut,'y',sizeof(cut));
memset(sum,0,sizeof(sum));
total_sum_number = 0;
dfs(1);
ans_number = 0;
for (int i = 0;i < total_sum_number;i++) {
if (sum[i] == closest_number){
ans_number++;
}
}
if (ans_number > 1){
cout << "rejected" << endl;
continue;
}
cout << target_number - closest_number;
for (int i = 0; i < final_pieces;i++) {
cout << " " << final_ans[i];
}
cout << endl;
}
return 0;
}