11K:张三丰的传人
- 总时间限制:
- 1000ms
- 内存限制:
- 30000kB
- 描述
-
张三丰凭借太极拳成为一代宗师;然而岁月不饶人,他希望找到传人,在有生之年将太极拳传于弟子发扬光大。然而,张三丰的太极拳有一个特点,学的时间越长,忘记的越多。一个弟子学习时间为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 <iostream> 2 #include <cmath> 3 using namespace std; 4 int ans[10000], temp; 5 double sum, eps = 1e-6; 6 bool dfs(int s, int x) //还要分的和为s,已经分完的最后一个数是x(为了递增顺序) 7 { 8 if(fabs(sum+1.0/s-1)<eps){ 9 ans[temp] = s; 10 temp++; 11 cout<<temp<<" "; 12 for(int i = 0; i < temp; i++){ 13 cout<<ans[i]<<" "; 14 } 15 cout<<endl; 16 return true; 17 } 18 if(sum>1+eps) return false; 19 if(sum+1.0/x*s/x<1-eps) return false; //最大也到不了1 剪枝 20 for(int i = x; i <= s/2; i++){ //要留一个数,所以循环到s/2就行了 21 ans[temp++] = i; 22 sum += 1.0/i; 23 if(dfs(s-i, i)) return true; 24 sum -= 1.0/i; 25 temp--; 26 } 27 return false; 28 } 29 int main() 30 { 31 int m; 32 cin >> m; 33 while (m--) 34 { 35 int s; 36 cin >> s; 37 sum = 0; 38 temp = 0; 39 if(!dfs(s, 2)) 40 cout<<"-1"<<endl; 41 } 42 return 0; 43 }
备注:又是照着标答写的,又是一道搜索题。要注意用fabs来对浮点数取绝对值,除的时候要用1.0使结果是double。
遇到这种题不要怂!搜就行了orz