刷题
首先是考虑直接复制的情况。
COW
COWCOW
COWCOWCOWCOW......
思路:
首先找到能够容纳N的最短的字符串(num和N进行的第一次比较),(注意是最短的字符串,这能够保证N一定出现在该找到的字符串的后半截,也就是说有减半而不越界的保证。)根据前文所说,该N位置一定出现在后半段,也就是说一定能够完成减半操作而不越界,所以使用一个i来找到最短字符串的长度之后除以二,即为要减去的长度。然后相当于是用减法更新了N的值,然后去判断N是否出现在原题给出的字符串的范围内,如果在则直接输出(注意,数组下标从0开始),否则继续按照这个思路来更新N,直至可以直接输出为止。(其实,N和num之间的比较从最开始就要进行)。
//先尝试直接复制
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int num;
ll N,i;
string s;
int main()
{
cin>>s;
cin>>N;//N从1开始计数
num=s.size();
while(num<N)
{
i=num;
//更新N
while(N>i)
i*=2;
i/=2;
N-=i;
}
cout<<s[N-1]<<endl;
return 0;
}
现在来看题目给出的复制方式
题目要求,先把字符串的最后一个字符复制添加到原来的串的末尾,然后把所有前缀照搬到后面,那么其余思路大体一致,只要是由于复制方式变化带来的N的更新方式的不同。
还是要首先找到能够容纳N的最短字符串,然后用i去存储最短字符串的长度,此时更新N=N-(i/2+1),若是N==0那么说明N原先指向特殊位置(原字符串的尾字母复制得到的),那么N=i,否则(N!=0)那么就照旧更新即可,其余思路一致。
//按照题目给出的复制方式
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int num;
string s;
ll N,i;
int main()
{
cin>>s;
cin>>N;
num=s.size();
while(N>num)
{
i=num;
while(N>i) i*=2;//找到能够容纳N的最短的字符串,最短的效果没有发生变化
//因为复制方式变了,所以减半更新N的操作也要相应的变化!
i/=2;//当前最短串的长度的一半
N=N-i-1;
if(N==0)//说明是特殊位置
N=i;
//如果不是特殊位置,那么N照旧更新即可
}
cout<<s[N-1]<<endl;
return 0;
}
8793

被折叠的 条评论
为什么被折叠?



