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.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
两处剪枝:1.当当前情况肯定超过1时
2.只递增尝试
注定失败的战争,也要拼尽全力去打赢它;
就算输,也要输得足够漂亮。