[洛谷 P3612 USACO17JAN]Secret Cow Code S
思路:分治
设原串长度为 (len),要查询的位置为 (pos),考虑如何一步步分治令 (pos) 变为小于等于 (len) 的数 (pos′),且 (s_{pos}=s_{pos′})。
先定义一个 (n) 记录何时字符串的长度大于 (pos),然后根据题意,很容易得出如果某个字符 (pos) 在长度为 (n) 的字符串的后半段,那么第
(pos−1−n/2) 一定与第 (pos) 个字符相同。
但是当 (n/2+1=pos) 时,(pos) 的值应该等于 (pos−1),即 (n/2),所以这种情况要特判,由此写出以下代码
while (n != len) {
n = n / 2;
if (pos <= n) continue;
n + 1 == pos ? pos = n : pos -= 1 + n;
}
总代码
#include<bits/stdc++.h>
using namespace std;
const int N=200000;
int ch[N];
int n,pos;
int main()
{
scanf("%s",ch+1);
cin>>pos;
int len=strlen(ch+1);
n=len;
while(n<pos)
{
n*=2;
}
while(n!=len)
{
n/=2;
if(pos<=n)continue;
pos==n+1?pos=n:pos=pos-1-n;
}
cout<<ch[pos]<<endl;
return 0;
}