【无标题】

刷题

首先是考虑直接复制的情况。

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;

}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值