18.06.27 16年期末11:张三丰的传人

描述

张三丰凭借太极拳成为一代宗师;然而岁月不饶人,他希望找到传人,在有生之年将太极拳传于弟子发扬光大。然而,张三丰的太极拳有一个特点,学的时间越长,忘记的越多。一个弟子学习时间为T,那么他只可以学习到总功力的1/T。假设张三丰计划用S的时间,他可以培养N个弟子,虽然可能每个弟子都无法完全学会,但是只要这N个弟子的总功力之和为1,张三丰就可以将S的时间,分配给这N个弟子,来完成自己的心愿;如果给定S之后,对于任何的N,都无法找到一种有效的分配方案,张三丰只能含恨而终。在这里,S,N和T均必须为正整数。

你的任务是:给定整数S,帮助张三丰找出一个整数N,以及一个分配方案。例如:S为10时,你帮助张三丰找到3个弟子,传授他们武功的时间分别为{2,4,4};S为2时,你无论如何无法找到这样一个方案,张三丰只能含恨而终。

输入

第一行是一个正整数m,表示测试数据的组数。
每组测试数据只有一行,一个正整数S( 1<=s<65536),表示张三丰计划传授太极拳的总时间。

输出

对每组测试数据:如果你可以帮助张三丰找到这样一组方案,首先输出正整数N,然后输出N个数分别代表分配给这N个弟子各自的时间,数据之间用空格隔开;如果你无法找到这样的分配方案,输出-1.

样例输入

3
1
2
10

样例输出

1 1
-1
3 2 4 4

提示注意:这样的方案可能有多组,你只需要输出任何一组;另外,本题目中浮点数的精度控制在1e-6.

 1 #include <cstdio>
 2 #include <string>
 3 #include <memory.h>
 4 #include <algorithm>
 5 #include <stdlib.h>
 6 #include <math.h>
 7 #include <iostream>
 8 #include<queue>
 9 #include <vector>
10 using namespace std;
11 
12 const double eps = 1e-6;
13 int s,time0;
14 vector<int> solution;
15 bool flag=false;
16 
17 bool is_equal(double a) {
18     if (a <= 1 + eps && a >= 1 - eps)
19         return true;
20     return false;
21 }
22 
23 void dfs(double sum,int now,int left) {
24     if (flag) 
25         return;
26     if (sum + 1 / (double)left > 1 + eps)
27         return;
28     if (is_equal(sum + 1 / (double)left)) {
29         flag = 1;
30         solution.push_back(left);
31         return;
32     }
33     for (int i = now; i < left-1; i++) {
34         solution.push_back(i);
35         dfs(sum + 1 / (double)i, i, left - i);
36         if (flag)
37             return;
38         solution.pop_back();
39     }
40 }
41 
42 
43 int main()
44 {
45     int t;
46     scanf("%d", &t);
47     while (t--) {
48         flag = false;
49         solution.clear();
50         scanf("%d", &time0);
51         dfs(0, 1, time0);
52         vector<int>::iterator i1 = solution.begin(),i2=solution.end();
53         if (flag)
54         {
55             printf("%d", solution.size());
56             for (; i1 != i2; i1++)
57                 printf(" %d", *i1);
58             printf("\n");
59         }
60         else
61             printf("-1\n");
62     }
63     return 0;
64 }
View Code

两处剪枝:1.当当前情况肯定超过1时

2.只递增尝试

猜你喜欢

转载自www.cnblogs.com/yalphait/p/9232114.html