对称美学,对称字符串

时间限制:1s 空间限制:256MB 限定语言:不限

题目描述:

对称就是最大的美学,现有一道关于对称字符串的美学。已知:

第 1 个字符串:R

第 2 个字符串:BR

第 3 个字符串:RBBR

第 4 个字符串:BRRBRBBR

第 5 个字符串:RBBRBRRBBRRBRBBR

相信你已经发现规律了,没错!就是第 i 个字符串 = 第 i - 1 号字符串的取反 + 第 i - 1 号字符串;取反(R->B, B->R);

现在告诉你 n 和 k,让你求得第 n 个字符串的第 k 个字符是多少。(k的编号从 0 开始)

输入描述:

第一行输入一个T,表示有T组用例;

接下里输入T行,每行输入两个数字,表示n, k

1 <= T <= 100;

1 <= n <= 64;

 

 

0 <= k < 2^(n-1);

输出描述:

输出T行表示答案;

输出 "blue" 表示字符是B;

输出 "red" 表示字符是R;

补充说明:

输出字符串区分大小写,请注意输出小写字符串,不带双引号

示例1

输入:

5

1 0

2 1

3 2

4 6

5 8

输出:

red

red

blue

blue

blue

说明:

第 1 个字符串:R -> 第0个字符为R

第 2 个字符串:BR -> 第1个字符为R

第 3 个字符串:RBBR -> 第2个字符为B

第 4 个字符串:BRRBRBBR -> 第6个字符为B

第 5 个字符串:RBBRBRRBBRRBRBBR -> 第8个字符为B

示例2

输入:

1

64 73709551616

输出:

red

 
function find(n, k) {
    if (n == 0) {
        return 'R';
    }
    let len = Math.pow(2, n);
    // 如果 k 在后半段,则与前一个字符串相同
    if (k >= len / 2) {
        let pos = k - len / 2;
        return find(n - 1, pos);
    } else {
        // 如果 k 在前半段,则与前一个字符串相反
        return find(n - 1, k) == 'R' ? 'B' : 'R';
    }
}

function main() {
    /*
    5 8
    n=5,k=8
    第 5 个字符串:RBBRBRRBBRRBRBBR  总字符串个数 2^(5-1) = 16,半数half=16/2=8;
    k=8 == half(8),说明第k=8个字符在后半部分,(从“第 1 个字符串:R  -> 第0个字符为R ”,这句话可以看出,数字符串的时候是从0开始数,所以8在后半段了)
    这串字符是继承的第4个字符串,没有进行翻转,且此字符在第4个字符串的位置为 8 - half(8)=0;
    第 4 个字符串:BRRBRBBR   总字符串个数 2^(4-1) = 8,半数half=8/2=4;
    k=0<half(4),说明第k=0个字符在前半部分,这串字符是经过第3个翻转的,则位置不变。
    第 3 个字符串:RBBR 总字符串个数  2^(3-1)=4,半数half=4/2=2;
    k=0<half(2),说明第k=0个字符在前半部分,这串字符是经过第2个翻转的,则位置不变;
    第 2 个字符串:BR  总字符串个数  2^(2-1)=2,半数half=2/2=1;
    k=0<half(1),说明第k=0个字符在前半部分,这串字符是经过第1个翻转的,则位置不变;
    第 1 个字符串:R  总字符串个数  2^(1-1)=1,到了第一个R。
    求出总共经过3次翻转,R->B->R->B,得到结果为blue
第 1 个字符串:R  -> 第0个字符为R                   2^(1-1)=1,到了第一个R。         k = 0    1,k = 0 R
第 2 个字符串:BR  -> 第1个字符为R                  2^(2-1)=2,半数half=2/2=1;     k = 1    2,k = 0 0在前半段,求 1,0 的反, B
第 3 个字符串:RBBR -> 第2个字符为B                 2^(3-1)=4,半数half=4/2=2;     k = 2    3,k = 0 0在前半段,求 2,0 的反, R
第 4 个字符串:BRRBRBBR  -> 第6个字符为B            2^(4-1)=8,半数half=8/2=4;     k = 6    4,k = 0 0在前半段,求 3,0 的反, B
第 5 个字符串:RBBRBRRBBRRBRBBR -> 第8个字符为B     2^(5-1)=16,半数half=16/2=8;   k = 8  8在后半段,就求 4, 8-8 =》 4,0     B
                        如果 k 在后半段,则与前一个字符串相同, 如果 k 在前半段,则与前一个字符串相反
    */
    // n, k, 求第 n 个字符串的 第 k 个字符为R 
    let res = find(n - 1, k) == 'R' ? "red" : "blue";
    console.log(res);
}

 

参考:https://www.nowcoder.com/discuss/443826793280278528

 

posted @ 2023-02-19 23:10  fengnovo  阅读(245)  评论(0编辑  收藏  举报