这道题没认真想,一开始还爆了空间。
题目详情
西西需要把输入的电压 1 伏通过一系列电压放大器放大成原来的 N 倍,然后输出。
西西现在手上有两种放大器:
第一种能够把X伏的电压放大成 2X−1 伏
第二种能够把X伏的电压放大成 2X+1 伏
放大器是串联(即按顺序放在一条线路上)的。
现在西西手上有用不完的放大器,他希望能组出一个电路,使用数量最少的放大器,使得电压被放大了刚好 N 倍。
方法
BFS(RE 50分)
思路
将两种操作分别添加进队列,找到合适答案后跳出。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include<bits/stdc++.h> using namespace std; struct data{ unsigned long long which,vol; data *prev; }QUEUE[5000005]; int head=0,tail=2; unsigned long long ANSQUEUE[5000005]; int GetAnswerQueue(){ data *now=&QUEUE[tail]; int len=0; while(now!=NULL){ len++; ANSQUEUE[len]=now->which; now=now->prev; } return len; } void Output(int len){ printf("%d\n",len-1); for(int i=len-1;i>=1;i--){ printf("%lld ",ANSQUEUE[i]); } } int main(){ freopen("amp.in","r",stdin); freopen("amp.out","w",stdout); int n; scanf("%d",&n); QUEUE[1].vol=1; QUEUE[1].which=0; QUEUE[1].prev=NULL; while(head<tail){ head++; if(QUEUE[head].vol>n)break; QUEUE[tail].vol=QUEUE[head].vol*2-1; QUEUE[tail].which=1; QUEUE[tail].prev=&QUEUE[head]; if(QUEUE[tail].vol==n){ int len=GetAnswerQueue(); Output(len); return 0; } tail++; QUEUE[tail].vol=QUEUE[head].vol*2+1; QUEUE[tail].which=2; QUEUE[tail].prev=&QUEUE[head]; if(QUEUE[tail].vol==n){ int len=GetAnswerQueue(); Output(len); return 0; } tail++; } printf("No solution"); return 0; }
|
判断奇偶性(AC 100分)
思路
由于能够出现答案的 N 都是奇数,所以提前特判,然后倒推。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include<bits/stdc++.h> using namespace std; int ans[1008616]; int main(){ freopen("amp.in","r",stdin); freopen("amp.out","w",stdout); unsigned long long n; scanf("%lld",&n); if(n%2==0){ printf("No solution"); return 0; } while(n!=1){ if(((n-1)/2+1)%2==1)n=(n+1)/2,ans[++ans[0]]=1; else n=(n-1)/2,ans[++ans[0]]=2; } printf("%d\n",ans[0]); for(int i=ans[0];i>=1;i--)printf("%d ",ans[i]); }
|
这道题明显一开始想复杂了,没有细推数据,下次还是要注意。