P3612 [USACO17JAN]Secret Cow Code S

题目链接 https://www.luogu.com.cn/problem/P3612

思路是看的dalao的。。。代码是模仿dalao的。。。Um...

光看懂题目我就用了好长时间啊。。。但是是一道很有意思的题目!

首先看到数据范围:n<=1018,那么显而易见,分治欢迎您!


 

梳理题意:

给定一个字符串,每次将其最后一个字符移到最前方,形成的新串接到原串后作为下一次操作的字符串,现询问第n个位置的字符。


 

解析题目:

拿cow距离,新串(cowwco)的前一半字符(cow)和上一个串(cow)完全一样,后一半字符(wco)的第一个字符('w'co)是前一半字符的最后一个(co'w'),剩余的字符(co)是前一半字符除了最后一个字符的所有('co'w)。所有的新串以此类推。


 

大致思路:

此题最重要的是找到题目规律并推出递归的式子。

拿n=8举例:先求出当前刚好包括n位置的串长,那么第八个字符出现在旋转两次后的字符串(即第三个字符串)中,则n=8位置的字符在旋转一次后的字符串(上一个串,即第二个串)中的位置为n=n-1-L/2

右边的n表示字符在最新串(第三个串)中的位置,左边的n为字符在上一个串(第二个串)中的位置。

通过上式可以推出:第三个串中n=8时的字符,在第二个串中的位置为n=1。

当n<num时,表示已经在初始字符串中找到在无限字符串中n所表示的字符。


 

放AC代码(好短!(bushi)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 string s;
 4 long long n,num,i;
 5 int main()
 6 {
 7     cin>>s>>n;
 8     num=s.length();
 9     while(num<n)
10     {
11         i=num;
12         while(n>i) i*=2;//求出当前刚好包括n位置的串长
13         i=i/2;//得到当前串的一半长
14         n-=(i+1);
15         if(n==0) n=i;
16     }
17     cout<<s[n-1];
18 }

 

posted @ 2022-04-03 23:21  爱吃虾滑  阅读(70)  评论(0编辑  收藏  举报