题目描述:
解题思路:
题目解读:
初始状态只有一个糖果,即x=1,给定想要获得的总糖果数y。
只能进行两种操作,分别是做2x-1和2x+1。给出从 x=1 到 目标数字 y 的操作步数和具体步骤。
示例1 从1到2,不可能实现,输出-1。
示例2 从1到3,一步操作2x+1即可。
示例3 从1到7,先2x+1,再2x+1即可。
找规律,2x-1和2x+1得到的都是奇数,因此这个算法只能对奇数生效,当y为偶数时,直接输出-1。正确路径每次得到的数都是奇数。
我们可以从终点反推起点 x=(1+-y)/2,每一步正确与否,依靠倒推结果是否为奇数来判定。
为奇数则继续下一步反推,为偶数则选择另一条路径进行反推,直到得到1。
最后的输出:记录步数i++即可实现,具体的倒推步骤则需要封装成数组,最后再倒序输出。
代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#define MAX 40
void Solve() {
int i=0,y; //i用来记录步数,y记录目标
int a[MAX]; //数组记录具体步骤
scanf("%d", &y);
if ( y % 2 == 0) { //偶数,直接输出-1
printf("-1\n");
return;
}
while(y!=1) { //奇数,且不为1
if (((y + 1) / 2) % 2 == 1) { //尝试走步骤1,满足则进行反推,同时i++,赋值a[i]
y = (y + 1) / 2;
a[i++] = 1;
}
else { //步骤1不满足,则走步骤2进行反推,同时i++,赋值a[i]
y = (y - 1) / 2;
a[i++] = 2;
}
}
printf("%d\n", i); //输出步数
while (i--) //循环输出具体步骤
{
printf("%d ", a[i]);
}
return;
}
int main() {
int t;
scanf("%d", &t);
while (t--) Solve();
return 0;
}
遇到的错误:
要注意输入输出的格式问题,根据题目要求给定的output,这里-1输出时,后面带有\n换行,否则报错。
结果步骤采用数组保存,存储后倒序输出即可,每个步骤间的空格若采用\t。空间过大,输出中加空格即可(即"%d ")。