目录
题目描述
输入描述
输出描述
用例
题目解析
算法源码
题目描述
对称就是最大的美学,现有一道关于对称字符串的美学。已知:
- 第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。
备注:输出字符串区分大小写,请注意输出小写字符串,不带双引号。
用例
输入 | 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 |
输入 | 1 64 73709551616 |
输出 | red |
说明 | 无 |
题目解析
上图所示,是第1~6个字符串,可以发现第6个已经很长了,那么本题的最多要求到第64个字符串,那么有多长呢?答:2^63,即 2^(n-1)。这个长度如果用字符串来存储的话,肯定爆内存,因此任何需要缓存字符串的动作都是禁止的。
我们只能找规律,来通过规律推导出第n个字符串的第k个字符。
那么规律是啥呢?
如上图黄框所示,我们可以发现,
第6个字符串的后半部分,和第5个字符串完全相同;
同理,
第5个字符串的后半部分,和第4个字符串完全相同;
第4个字符串的后半部分,和第3个字符串完全相同;
第3个字符串的后半部分,和第2个字符串完全相同;
第2个字符串的后半部分,和第1个字符串完全相同;
因此,如果我们要找到的k位于第n个字符串的后半部分,假设为get(n, k),那么其等价于 get(n-1, k - 2^(n-2)),按此逻辑递归,就可以一直找到第2个字符串或第1个字符串,而这两个字符串很好确认,分别是”R“,”BR“。
那么如果我们要找到第k个字符串,位于第n个字符串的前半部分呢?
可以发现,其实get(n,k),如果k <= 2^(n-2) ,则相当于 get(n-1, k) 的颜色取反。
算法源码
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const lines = [];
let t;
rl.on("line", (line) => {
lines.push(line);
if (lines.length === 1) {
t = lines[0] - 0;
}
if (t && lines.length === t + 1) {
lines.shift();
const arr = lines.map((line) => line.split(" ").map(Number));
getResult(arr);
lines.length = 0;
}
});
function getResult(arr) {
for (let [n, k] of arr) {
console.log(getNK(n, k + 1)); // 让k的索引从1开始
}
}
function getNK(n, k) {
// 题目没说异常如何处理,因此我默认输入无异常,比如n=1的话,则k只能取1
if (n === 1) {
return "red";
}
// n=2的话,则k只能取1或2
if (n === 2) {
if (k === 1) return "blue";
else return "red";
}
// 第n个字符串的一半长度half
let half = 1 << (n - 2);
if (k > half) {
return getNK(n - 1, k - half);
} else {
return getNK(n - 1, k) === "red" ? "blue" : "red";
}
}