嵊州D3T3 light
光恰似水
兄弟俩曾经 k 次受到过父母的物质激励。
一开始,兄弟俩的能力值为 1,最后,兄弟俩的能力值是 1 + (2 ^k−1)/ n 。
当兄弟俩受到价值为 m 的物质的激励时,他们的能力值会变成原来的 1 + 1/ m 倍。
但是现在,他们已经不记得父母给他们的物质激励的价值是多少了。
请你给出一种任意可行的方案。
Input
第一行一个整数 T,表示数据组数。
对于每组数据,一行两个整数,代表 n, k。
Output
输出共 T 行。
对于每组数据,输出 k 个整数 m
表示一种可能的答案,或者一个空行。
Examples
light.in | light.out |
1 4 3 | 1 4 10 |
Notes
对于所有数据,满足 0 ≤ T ≤ 10 , 0 ≤ k ≤ 60 , 1 ≤ n ≤ 10^18。
Subtask1[11pts]
T = 0
Subtask2[20pts]
k = 0
Subtask3[28pts]
T = 1 , n, k ≤ 3
Subtask4[41pts]
无特殊限制
开始没有看懂题目
就先写了个函数模拟
//用函数模拟
void func(int time,int en){
if(time>k) return;
if(time==k&&en==+((pow(,k))-)/(n*1.0f)) return;
for(m[time]=;m[time]<=;m[time]++){
if(en==+((pow(,k))-)/(n*1.0f)) return;
else func(time+,en*(+m[time]));
}
;
}
然后主函数的话
int t;
cin>>t;
for(int i=;i<t;i++){
cin>>n>>k;
func(,);
for(int j=;j<=k;j++)
cout<<m[j]<<" ";
cout<<endl;
}
std
其实它是一个递归调用的过程
void work(long long n, long long k)
{
if (k == ) {puts(""); return;}//边界条件1: 特殊值
if (k == ) {printf("%lld\n", n); return;}//边界条件2:回溯到了第1次 if (n & )//如果n在二进制下末位是一的话(即n为奇数)……这样的话
{
printf("%lld ", n);
work((n + ) >> , k - ); //右移n+1一位,舍弃多余的位,相当于(n+1)/2
}
else//否则n为偶数……
{
printf("%lld ", n - + (1LL << k));
work(n >> , k - );//右移n一位,舍弃多余的位,相当于n/2
}
}
所以,再加一个主函数内的调用即可
#include <cstdio> using namespace std; long long n, k; int T; void work(long long n, long long k)
{
if (k == ) {puts(""); return;}//边界条件1: 特殊值
if (k == ) {printf("%lld\n", n); return;}//边界条件2:回溯到了第1次 if (n & )//如果n(的二进制数)是像1111111111111……这样的话 (在十进制下就是要2^n-1这样的)
{
printf("%lld ", n);
work((n + ) >> , k - ); //把n+1右移一位,舍弃多余的位(向下取整),相当于int强制转换,但不相当于(n+1)/2(向零取整)
}
else//否则……
{
printf("%lld ", n - + (1LL << k));
work(n >> , k - );//右移n一位,舍弃多余的位,相当于n/2
}
} int main()
{
// freopen("light.in", "r", stdin);
// freopen("light.out", "w", stdout); scanf("%d", &T);
while (T--)
{
scanf("%lld%lld", &n, &k);
work(n, k);
}
return ;
}
OK!