알고리즘 설계 및 분석 01 2.3 시퀀스

★ 제목 설명

숫자 N의 시작에 불과 시퀀스를 감안할 때

레인 1은 X만을 시퀀스까지 X / 2 세 번째 라운딩 2 개조, 시퀀스 X가 삭제 라운딩 X X / 2에서 원래의 위치에 삽입으로 분할 될 시퀀스 번호 X보다 크다 0과 1.

R 1의 개수의 제 L 번호 간의 Q 마지막 시퀀스 번호.

★ 입력 형식

R 데이터의 길이는 최종 시퀀스되도록보다 크지.

★ 출력 형식

정수, R 1 수의 첫번째 수와 마지막 시퀀스 번호 L.

★ 샘플 입력

4 3 6

★ 샘플 출력

2

★ 팁

샘플을 다음과 같이 변경의 순서 : 4 → 202 → 1,010,101
번째 수가 1 내지 6 사이의 두 개의 번호를 갖는다.

/*
先计算01序列长度和n大小的关系
0  0
1  1 
2  101 
3  111 
4  1010101
5  1011101
6  1110111
7  1111111
8  101010101010101 
9  101010111010101
10 101110101011101 
11 101110111011101
12 111011101110111
13 111011111110111
14 111111101111111
15 111111111111111
16 1010101010101010101010101010101 

所以长度关系为
    L=2^0+2^1+ ……+2^t,2^t≤n 
 

考察分治算法 
这个01序列是根据分治思想左右对称的 
*/

#include<bits/stdc++.h>
using namespace std;

int N,L,R;

int df(int n, long long Len, int pos){
    if(R<pos-Len/2 || pos+Len/2<L) return 0;
    if(Len==1) return  n%2;
    
    int dis = (Len+1)/4;
    if(L<=pos && pos<=R) return df(n/2, Len/2, pos-dis) + n%2 + df(n/2, Len/2, pos+dis);
    if(R<pos) return df(n/2, Len/2, pos-dis);
    if(pos<L) return df(n/2, Len/2, pos+dis);
} 


int main(){
    cin>>N>>L>>R;

    long long Len=0;
    for(int i=0; pow(2,i)<=N; ++i) Len+=pow(2,i);

    cout<<df(N, Len, (1+Len)/2)<<endl;
    
    return 0;
}

추천

출처www.cnblogs.com/yejifeng/p/12044416.html