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

posted @ 2020-06-17 12:12  timeaftertime  阅读(344)  评论(0编辑  收藏  举报