(紀中)1604. 【市選模擬題】電壓放大器【數學】

(File IO): input:amp.in output:amp.out
時間限制: 1000 ms 空間限制: 128000 KB 具體限制 Special Judge


題目描述
西西需要把輸入的電壓11伏通過一系列電壓放大器放大成原來的NN倍,然後輸出。
西西現在手上有兩種放大器:
第一種能夠把XX伏的電壓放大成2X12X-1
第二種能夠把XX伏的電壓放大成2X+12X+1
放大器是串聯(即按順序放在一條線路上)的。
現在西西手上有用不完的放大器,他希望能組出一個電路,使用數量最少的放大器,使得電壓被放大了剛好NN倍。


輸入
一行一個正整數N(1<=N<=2109)N(1<=N<=2*10^9)

輸出
如果無法組成電路則輸出一行NoNo solutionsolution
否則輸出兩行,第一行一個整數表示最少的放大器個數KK,第二行KK個用空格隔開的1122,表示放大器序列。11表示第一種,22表示第二種,其中左邊爲輸入端。如果有多解輸出任意一組。


樣例輸入
5

樣例輸出
2
2 1


數據範圍限制
2020%的數據中 N<=1000N<=1000
5050%的數據中,N<=1000000N<=1000000
100100%的數據如題。


提示
先經過放大器2212+1=31*2+1=3,然後經過11321=53*2-1=5。滿足要求


解題思路
題目大意:給你一個11,讓你經過多次操作(分兩種:2x+12x+12x12x-1)變爲nn這個數,求最少要多少步,並輸出操作序號。

主要思路(分兩種):
(1)爆搜無極限 本蒟蒻當時就只打了暴搜QWQ,6060 ,唉,可惜時間複雜度不允許啊……

(2)我們可以從奇偶性分析,一開始的11爲奇數開始模擬一下所有步驟:
1.1.奇數×2+1=×2+1=奇數
2.2.偶數×2+1=×2+1=奇數
3.3.奇數×21=×2-1=奇數
4.4.偶數×21=×2-1=奇數
那這麼看來,這個變化中的序列肯定是個奇數序列了。SoSo,只要n是偶數輸出NoNo solutionsolution
我們開始分析一下樣例:55
肯定是先第二種再第一種,這時我們反着推:5+1/2=3,(31)/2=1(5+1)/2=3,(3-1)/2=1
我們這時可以思考到:爲什麼55只能+1+1/2/2,而33可以1-1/2/2呢?我們可以先列一個奇數表
表:1,3,5,7,9,11,13,15,17,191 ,3 ,5 ,7 ,9 ,11 ,13 ,15 ,17 ,19……
標記 +1,1,+1,1,+1,1,+1,1,+1,1+1,-1,+1,-1,+1,-1, +1 ,-1, +1, -1……
我們可以發現+11+1,-1好像就是按他們在這個奇數數列中位置而變。那就是求項數 % 2== 什麼了。
那這就好辦了每次去判斷現在他的項數爲偶數就x1/2(x-1)/2否則就x+1/2(x+1)/2


代碼·

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<map>
using namespace std;
int n,x,t,ans[105];
int main()
{
	freopen("amp.in","r",stdin);
    freopen("amp.out","w",stdout);
    scanf("%d",&n);
    if(n%2==0)
		printf("No solution");
	else
	{
		x=n,t=0;
		while(x!=1)
		{
			if(((x-1)/2+1)%2==1)
				x=(x+1)/2,ans[++t]=1;
			else
				x=(x-1)/2,ans[++t]=2;
		}
			
		printf("%d\n",t);
		for(int i=t;i>=1;--i)
			printf("%d ",ans[i]);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章