#2019120500007-CSP Day1T1

CSP-S D1T1 题解
咕咕咕的Day1过去了

我的做法

通过手动计算,我画出了\(n=4\)时候的这张表格:

(请注意:本表格倒序存放)

第4位 第3位 第2位 第1位
0 0 0 0
1 0 0 0
1 1 0 0
0 1 0 0
0 1 1 0
1 1 1 0
1 0 1 0
0 0 1 0
0 0 1 1
1 0 1 1
1 1 1 1
0 1 1 1
0 1 0 1
1 1 0 1
1 0 0 1
0 0 0 1

在这张表格里,我发现了这些规律:

  1. \(n\leq 4\)时,数据都是本表格的一部分,如:\(n=2\)时是前\(2 \times 2^2\)格,\(n=3\)时是前\(2 \times 2^3\)
  2. \(n\)每增加1,相当于把表格前三列向下翻转,然后在最后一列前半部分添加1,后半部分添加0,具体过程如下
    表格变换

(这是我一开始找到的规律,打算开始模拟,然鹅我发现)

  1. (来了来了)对于寻找序列里第\(t\)个(为了描述方便我们从把编号改为\(1-2^n\)),定义\(l=1,r=2^n\),显然\(mid=\frac{l+r}{2}\)(按照C++,这里\(mid\)应该比真实的平均值少0.5,所以会出现最后判断不停止的情况,我的做法是加上0.5,让它一直保持在中间,不知道想的是否全面),加完0.5以后得到的\(mid\)\(p\)比较,如果小于那么所输出数的第一位一定是0,否则是1

  2. 就在我这样写完之后,试了一组小样例发现不对!因为什么呢?因为当第一位是1时,后面的一组数据会是1在前,0在后,于是有了下面这一段代码:

    long long p=k+1;
    long long tot=quick_pow(2,n);
    long long l=1,r=tot;
    int y=n;
    bool ishang=1;
    while(y--){
        double mid=(l+r)/2;
        if(p<mid+0.5){
            if(y==n) printf("0"),ishang=1;
            else if(ishang) printf("0");
            else if(!ishang) printf("1"),ishang=1;
            r=mid;
        }
        if(p>mid+0.5){
            if(y==n) printf("1"),ishang=0;
            else if(!ishang) printf("0");
            else if(ishang) printf("1"),ishang=0;
            l=mid;
        }
    }

(自认为)复杂度可以达到\(O(n)\),虽然咕咕了(莫名自信)

Day2跟着混吧,没什么打算

代码贴上,欢迎质疑

(对了我还是一个骗分的小宝宝)

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
long long k;
int n;
int h[70][50000];
int ansd[70];
int cnt=3;
long long quick_pow(long long a,long long b){
    if(b==1){
        return a;
    }
    else if(b%2==0){
        b/=2;
        return quick_pow(a,b)*quick_pow(a,b);
    }
    else{
        b/=2;
        return quick_pow(a,b)*quick_pow(a,b)*a;
    }
}


int main(){
//  freopen("code.in","r",stdin);
//  freopen("code.out","w",stdout);
    scanf("%d%lld",&n,&k);
    h[1][1]=0,h[2][1]=0,h[3][1]=0;
    h[1][2]=1,h[2][2]=0,h[3][2]=0;
    h[1][3]=1,h[2][3]=1,h[3][3]=0;
    h[1][4]=0,h[2][4]=1,h[3][4]=0;
    h[1][5]=0,h[2][5]=1,h[3][5]=1;
    h[1][6]=1,h[2][6]=1,h[3][6]=1;
    h[1][7]=1,h[2][7]=0,h[3][7]=1;
    h[1][8]=0,h[2][8]=0,h[3][8]=1;
    if(n==1){
        if(k==1)printf("1\n");
        else printf("0\n");
        return 0;
    }
    else if(n==2){
        for(int i=n;i>=1;i--){
            printf("%d",h[i][k+1]);
        }
        printf("\n");
        return 0;
    }
    else if(n==3){
        for(int i=n;i>=1;i--){
            printf("%d",h[i][k+1]);
        }
        printf("\n");
        return 0;
    }
    else {
        long long p=k+1;
        long long tot=quick_pow(2,n);
        long long l=1,r=tot;
        int y=n;
        bool ishang=1;
        while(y--){
            double mid=(l+r)/2;
            if(p<mid+0.5){
                if(y==n) printf("0"),ishang=1;
                else if(ishang) printf("0");
                else if(!ishang) printf("1"),ishang=1;
                //printf("0");
                r=mid;

            }
            if(p>mid+0.5){
                if(y==n) printf("1"),ishang=0;
                else if(!ishang) printf("0");
                else if(ishang) printf("1"),ishang=0;
                l=mid;
            }
        }
    }
    printf("\n");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/liuziwen0224/p/11992337.html