P2328 [SCOI2005]超级格雷码

P2328 [SCOI2005]超级格雷码

暴力出奇迹喵!

这是一道模拟题

你会发现和 P5657 格雷码【民间数据】有异曲同工之妙,这道题直接按照上边链接题目的操作步骤 暴力模拟 就可以啊

我们观察 n=2n=2n=2 时候格雷码是这样操作的

在线引用链接题面描述:

带大家模拟一下:

比如 n=4

先生成1位:

也就是 0,1,2,3

然后生成两位:

也就是先把上一层的复制下来,顺序排好,然后再逆序排一遍,然后再顺序排一遍,再逆序排一遍。。。然后一小层作为一个分界,每一层的最左端都依次加上相应的字符 0,1,2,,,n-1

00 , 01 , 02 , 03 ,

13 , 12 , 11 , 10 ,

20 , 21 , 22 , 23 ,

33 , 32 , 31 , 30

n,B取其他值的时候也是一样的模拟

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<queue>

using namespace std;

typedef long long ll;

inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

const int maxn=65540;
string s[maxn],a[maxn];
int n,b,tot=1,cnt=1;
bool flag=0;

char chang(int x)
{
    char p;
    if(x<=9) p=(char)(x+48);
    else{
        p=(char) 65+x-10;
    }
    return p;
}

void work1(int k)
{
    char p=chang(k);
    for(int i=1;i<=tot;i++){
        s[cnt]=p+a[i];
        cnt++;
    }
}

void work2(int k)
{
    char p=chang(k);
    for(int i=tot;i>=1;i--){
        s[cnt]=p+a[i];
        cnt++;
    }
}

int main()
{
    n=read();b=read();
    tot=b;
    for(int i=1;i<=tot;i++){
        char p=chang(i-1);
        s[i]+=p;
    }   
    for(int t=2;t<=n;t++){
        flag=0;
        cnt=1;
        for(int i=1;i<=tot;i++) a[i]=s[i];
        for(int k=0;k<b;k++){
            if(flag==0) work1(k);
            else work2(k);
            flag^=1;
        }
        tot=cnt-1;
    }
    for(int i=1;i<=tot;i++) cout<<s[i]<<"
";
    return 0;
}
原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11921491.html