1604. 电压放大器(amp)

1604. 电压放大器(amp)

题目描述

西西需要把输入的电压1伏通过一系列电压放大器放大成原来的N倍,然后输出。
西西现在手上有两种放大器:
第一种能够把X伏的电压放大成2X-1伏
第二种能够把X伏的电压放大成2X+1伏
放大器是串联(即按顺序放在一条线路上)的。
现在西西手上有用不完的放大器,他希望能组出一个电路,使用数量最少的放大器,使得电压被放大了刚好N倍。

输入

一行一个正整数N(1<=N<=2*10^9)

输出

如果无法组成电路则输出一行No solution
否则输出两行,第一行一个整数表示最少的放大器个数K,第二行K个用空格隔开的1或2,表示放大器序列。1表示第一种,2表示第二种,其中左边为输入端。如果有多解输出任意一组。

样例输入

5

样例输出

2
2 1

数据范围限制

20%的数据中 N<=1000
50%的数据中,N<=1000000
100%的数据如题。

提示

先经过放大器2,12+1=3,然后经过1,32-1=5。满足要求

思路:
根据题意,初值为1,所以第一个放大器要选2x+1。

接下来因为2x为偶数,所以-1和+1为奇数,故偶数倍是不可能的。

然后把前几种可能生成的倍数情况打表,不难发现所有的奇数都可以生成。

n一定是由n/2,n/2+1中的一个数通过放大器得来。具体通过哪个放大器,可找一下规律。如果n/2是个偶数,就选n/2+1通过2x-1得来,反之由n/2通过2x+1得来。
在这里插入图片描述

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=2e9;
long long n,a[50],tot;
int main()
{
	fre(amp);
	scanf("%lld",&n);
	if(n%2==0) printf("No solution\n");
	while(n!=1)
	{
		long long temp=n/2;
		if(temp%2==1) a[++tot]=2,n=temp;
		else a[++tot]=1,n=temp+1;
	}
	printf("%lld\n",tot);
	for(long long i=tot;i>=1;i--) printf("%lld ",a[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/bigwinner888/article/details/105981083
今日推荐