- 信號分析
Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
半人馬座(Centaurus)不僅有着美麗的傳說,其中的比鄰星還是距離太陽系最近的恆星。C博士是一直熱衷於對地外文明的探測,最近他發現了一組來自半人馬座的奇怪電波信號:1 1 3 1 5 3 7 1……,她懷疑這是來自那裏的遙遠文明對地球的問候。經過她和助手們的努力,終於發現這是一個很有規律的頻率信號a1,a2,a3,……。其中a1=1,a3=3這是信號的開始標誌,其餘時刻的頻率有如下關係:
a2n = an
a4n+1 = 2a2n+1 - an
a4n+3 = 3a2n+1 - 2*an
(n>=1)
信號可能很長,其中會有一些分隔標誌。C博士在研究中發現這些分隔標誌其實是很容易就可以判別出來的,因爲它就滿足an = n。
爲了更進一步發掘這一長串信號的含義,C博士需要知道a1,a2,……,aL中分隔標誌有多少個。
Input
只有一個整數L(1<=L<232),表示所要分析信號的長度。
Output
輸出一個整數,爲這段長L的信號中分隔標誌的個數。
Sample Input
8
這道題的目的是找二進制數中的迴文數,所以先要把十進制轉化成二進制
因爲數字是從1開始
當二進制數爲1位時,迴文數有1個 1
當二進制數爲2位時,迴文數有1個 11
當二進制數爲3位時,迴文數有2個 101,111
當二進制數爲4位時,迴文數有2個 1001,1111
當二進制數爲5位時,迴文數有4個 10001,10101,11011,11111
當二進制數爲6位時,迴文數有4個 100001,101101,110011,111111
所以我們可以看出,當二進制數爲X位時,迴文數個數爲2的(X+1)/2-1次方,所以當二進制數爲X位時,從第1到第X-1位的迴文數肯定全部包括在內,而第X位二進制數,要分情況討論,如果X爲偶數,則看其第二位到第X/2位的值是多少,如果X爲奇數,則看其第二位到第X/2+1位的值,設其爲n,則以小於n開頭的二進制迴文數肯定在我們所求範圍之內,然後在考慮以n開頭的二進制迴文數在不在我們的範圍內,
這其中涉及到二進制轉換成10進制
接下來就是計算符合條件的數字的具體數目了,代碼思路如前面所說
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
vector<int> dtob(long long int n){
vector<int>v1;
vector<int>v2;
while(n!=0){
v1.push_back(n%2);
n/=2;
}
int len=v1.size();
for(int i=len-1;i>=0;i--){
v2.push_back(v1[i]);
}
return v2;
}
int btod(vector<int>v){
int len=v.size();
int result=0;
for(int i=0;i<len;i++){
if(v[i]==1){
result+=pow(2,len-i-1);
}
}
return result;
}
int main(){
long long int num;
cin>>num;
vector<int>v;
v=dtob(num);
int len=v.size();
int sum=0;
for(int i=1;i<len;i++){
sum+=pow(2,(i+1)/2-1);
}
if(len%2==0){
bool flag=true;
vector<int>temp;
for(int i=1;i<len/2;i++){
temp.push_back(v[i]);
}
int add1=btod(temp);
sum+=add1;
for(int i=len/2-1,j=len/2;i>=0&&j<len;i--,j++){
if(v[i]<v[j]){
sum++;
flag=false;
break;
}
else if(v[i]>v[j]){
flag=false;
break;
}
else{
}
}
if(flag){
sum++;
}
}
else{
bool flag=true;
vector<int>temp;
for(int i=1;i<=len/2;i++){
temp.push_back(v[i]);
}
int add1=btod(temp);
sum+=add1;
for(int i=len/2-1,j=len/2+1;i>=0&&j<len;i--,j++){
if(v[i]<v[j]){
sum++;
flag=false;
break;
}
else if(v[i]>v[j]){
flag=false;
break;
}
}
if(flag){
sum++;
}
}
cout<<sum<<endl;
}