P3612 [USACO17JAN] Secret Cow Code S
题目描述
奶牛们正在实验秘密代码,并设计了一种方法用于生成无限长度的字符串,作为他们代码的一部分。
给定一个字符串 s,令 F(s) 为 s 后接 s 向右“旋转”一个字符的结果(在右旋转中,s 的最后一个字符旋转并成为新的第一个字符)。给定初始字符串 s,奶牛们通过重复应用 F 来构建他们的无限长度代码字符串;因此每一步都会使当前字符串的长度翻倍。
给定初始字符串和一个索引 N,请帮助奶牛计算无限代码字符串中第 N 个位置的字符。
输入格式
输入由一行组成,包含一个字符串和 N。字符串最多由 30 个大写字母组成,且 N≤1018。
请注意,N 可能太大,无法放入标准的 32 位整数中,因此你可能需要使用 64 位整数类型(例如,C/C++ 中的 "long long")。
输出格式
请输出从初始字符串构建的无限代码字符串的第 N 个字符。第一个字符的位置为 N=1。
显示翻译
题意翻译
输入输出样例
输入 #1复制
COW 8
输出 #1复制
C
说明/提示
在这个例子中,初始字符串 COW 按以下方式扩展:
COW -> COWWCO -> COWWCOOCOWWC
import java.io.*;public class Main {static char[] S;static long L;public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String[] sp = br.readLine().split(" ");S = sp[0].toCharArray();L = S.length;long N = Long.parseLong(sp[1]);System.out.println(f(N));}static char f(long pos) {long len = L; // 当前段长度while (len < pos) len <<= 1; // 找到最小的 len >= pos// 从最大段倒推while (len > L) {len >>= 1; // 前半段长if (pos == len + 1) { // 后半段第一个 → 前一轮末尾pos = len; } else if (pos > len + 1) { // 后半段其余 → 映射到前一轮pos -= len + 1;}}return S[(int) (pos - 1)]; // 回到初始串}
}
S[(int)(pos - 1)]:
-
算法里
pos一直是 1-base,pos - 1得到 0-base 索引 -
强制
(int)是因为pos是long,而数组下标必须是int
