(File IO): input:amp.in output:amp.out
時間限制: 1000 ms 空間限制: 128000 KB 具體限制 Special Judge
題目描述
西西需要把輸入的電壓伏通過一系列電壓放大器放大成原來的倍,然後輸出。
西西現在手上有兩種放大器:
第一種能夠把伏的電壓放大成伏
第二種能夠把伏的電壓放大成伏
放大器是串聯(即按順序放在一條線路上)的。
現在西西手上有用不完的放大器,他希望能組出一個電路,使用數量最少的放大器,使得電壓被放大了剛好倍。
輸入
一行一個正整數
輸出
如果無法組成電路則輸出一行
否則輸出兩行,第一行一個整數表示最少的放大器個數,第二行個用空格隔開的或,表示放大器序列。表示第一種,表示第二種,其中左邊爲輸入端。如果有多解輸出任意一組。
樣例輸入
5
樣例輸出
2
2 1
數據範圍限制
的數據中
的數據中,
的數據如題。
提示
先經過放大器,,然後經過,。滿足要求
解題思路
題目大意:給你一個,讓你經過多次操作(分兩種:和)變爲這個數,求最少要多少步,並輸出操作序號。
主要思路(分兩種):
(1)爆搜無極限 本蒟蒻當時就只打了暴搜QWQ,分 ,唉,可惜時間複雜度不允許啊……
(2)我們可以從奇偶性分析,一開始的爲奇數開始模擬一下所有步驟:
奇數奇數
偶數奇數
奇數奇數
偶數奇數
那這麼看來,這個變化中的序列肯定是個奇數序列了。,只要n是偶數輸出 。
我們開始分析一下樣例:
肯定是先第二種再第一種,這時我們反着推:。
我們這時可以思考到:爲什麼只能再,而可以再呢?我們可以先列一個奇數表
表:
標記
我們可以發現好像就是按他們在這個奇數數列中位置而變。那就是求項數 % 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]);
}
}