洛谷-P3612 [USACO17JAN]Secret Cow Code S

题目描述

The cows are experimenting with secret codes, and have devised a method for creating an infinite-length string to be used as part of one of their codes.

Given a string ss, let F(s)F(s) be ss followed by ss "rotated" one character to the right (in a right rotation, the last character of ss rotates around and becomes the new first character). Given an initial string ss, the cows build their infinite-length code string by repeatedly applying FF; each step therefore doubles the length of the current string.

Given the initial string and an index NN, please help the cows compute the character at the NNth position within the infinite code string.

奶牛正在试验秘密代码,并设计了一种方法来创建一个无限长的字符串作为其代码的一部分使用。

给定一个字符串,让后面的字符旋转一次(每一次正确的旋转,最后一个字符都会成为新的第一个字符)。也就是说,给定一个初始字符串,之后的每一步都会增加当前字符串的长度。

给定初始字符串和索引,请帮助奶牛计算无限字符串中位置N的字符。

输入格式

The input consists of a single line containing a string followed by NN. The string consists of at most 30 uppercase characters, and N \leq 10^{18}N≤1018.

Note that NN may be too large to fit into a standard 32-bit integer, so you may want to use a 64-bit integer type (e.g., a "long long" in C/C++).

第一行输入一个字符串。该字符串包含最多30个大写字母,并 N \leq 10^{18}N≤1018 。

第二行输入N。请注意,数据可能很大,放进一个标准的32位整数可能不够,所以你可能要使用一个64位的整数类型(例如,在C / C++ 中是 long long)。

输出格式

Please output the NNth character of the infinite code built from the initial string. The first character is N=1N=1.

请输出从初始字符串生成的无限字符串中的位置的字符。第一个字符是 N=1N=1.。

输入输出样例

输入 #1复制

COW 8

输出 #1复制

C

说明/提示

In this example, the initial string COW expands as follows:

COW -> COWWCO -> COWWCOOCOWWC

12345678

感谢@y_z_h 的翻译

 

分析:

这题本来我的想法是,输入字符串s和数字n,while循环判断s.length和n的大小,若s的长度<n,那么就将s扩展一次,直到能直接s[n]取出其中第n个元素即可,但是,数据太大,会mle,附上代码(只能过第一个数据):

using namespace std;
string s;
string temps;
unsigned long long int n;
int main()
{
	cin>>s;
	cin>>n;
	while(s.length()<n)
	{
		temps=s;
		temps=temps[temps.length()-1]+temps;
		//cout<<"temps1 "<<temps<<endl; 
		temps = temps.substr(0, temps.length() -1);
		//cout<<"temps2 "<<temps<<endl; 
		//reverse(temps.begin(),temps.end());
		s+=temps;
	}
	//cout<<s<<endl;
	cout<<s[n-1];
	//cout<<s[n];
	//cout<<s[n+1];
	return 0;
}

没办法,过不去,去看看题解吧,然后发现大佬和我的想法类似不过我是扩展字符串s来满足n,它是缩小n来满足字符串s,这里是他的思路:

https://www.luogu.com.cn/blog/user34110/solution-p3612

经这位大佬的提示,我开始去寻找n缩小之后的关系,然后输出对应的s[n]即可

大佬的是char数组从1开始计数

我写的是string,从0开始计数,有一些小小的差别,但核心思想是一样的

附上AC代码:

#include<iostream>
using namespace std;
string s;
int num;
unsigned long long int n;
int main()
{
	cin>>s;
	cin>>n;
	int num=s.length();
	//cout<<"num "<<num<<endl;
	while(num<n)
	{
		unsigned long long int i=num;
		while(n>i*2) i=i*2;
		n-=i;
		n--;
		if(n==0)
		n=i;
		//cout<<"inner n "<<n<<endl;
	}
	//cout<<"hello"<<endl;
	//cout<<"n "<<n<<endl;
	cout<<s[n-1];
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值