P3612 [USACO17JAN]Secret Cow Code S

文章介绍了如何解决一个关于密码操作的编程题,其中涉及字符串处理、递归算法和动态规划。初始密码为ABC,每次操作是将字符串复制并反转一部分然后连接,目标是找出经过特定次数操作后的特定位置的字符。作者通过分析操作模式,利用递归函数实现了求解第888个字符的过程,并在修改数据类型后成功获得正确答案。
摘要由CSDN通过智能技术生成

闲着没事写篇题解。
P3612 [USACO17JAN]Secret Cow Code S

题目大意:

一群闲着没事的奶牛研究密码,设初始密码为“ABC”(题目给出的“COW”没那么好推算),那么:

1.1次操作后为“ABC”+“CAB”=“ABCCAB
2.2次操作后为“ABCCAB”+“BABCCA”=“ABCCABBABCCA
3.3次操作后为“ABCCABBABCCA”+“AABCCABBABCC”=“ABCCABBABCCAAABCCABBABCC
……
以此类推。

解题思路:

从推导过程中,我们可以发现,一次操作,可以分成以下几步:
1.将字符串复制;
2.将复制出的字符串的最后一个字母挪到第一个字符的位置;
3.连接两个字符串。
所以,我们设字符串为“ABC”,求密码的第 8 8 8个字符的解题过程如下:
0 0 0次操作: 3 3 3位字符串;
1 1 1次操作: 6 6 6位字符串;
2 2 2次操作: 12 12 12位字符串;
6 ≤ 8 ≤ 12 6\le8\le12 6812 8 − 6 = 2 8-6=2 86=2,所以,我们可以知道,这个要求的字符在第二次操作中新增字符串的第2位,根据规律,我们得出,这个字符是第 2 2 2次操作前,第 1 1 1次操作后的第 1 1 1位。在重复以上操作,我们发现 1 ≤ 3 1\le3 13,那么,这个字符就是初始字符串中的第 1 1 1位,为A

代码实现:

理论存在,实践开始。
根据上边的解题步骤,我们列出以下代码:

#include<bits/stdc++.h>
using namespace std;
char a[35];
int m,n,l;
char dg(int l,int r,int L,int R,int p){
	if (p<=m){
		return a[p];
	}
	if (p<=r){
		return dg(l,r/2,r/2+1,r,p);
	}
	else{
		long long rk=p-L+1;
		if (rk==1){
			return dg(l,r/2,r/2+1,r,r);
		}
		else{
			return dg(l,r/2,r/2+1,r,rk-1);
		}
	}
}
int main(){
	cin>>a+1>>n;
	m=strlen(a+1);
	l=m;
	while (l<n){
		l*=2;
	}
	cout<<dg(1,l/2,l/2+1,l,n);
}

提交结果:
错误结果
只有50分,本蒟蒻反复检查代码没发现问题,后来瞟了一眼数据范围,发现
int小了,于是把所有的int换成longlong之后,成了这样:

#include<bits/stdc++.h>
using namespace std;
char a[35];
long long m,n,l;
char dg(long long l,long long r,long long L,long long R,long long p){//不开long long见祖宗(确信)
	if (p<=m){
		return a[p];
	}//如果在初始字符串内,返回第p个字符
	if (p<=r){
		return dg(l,r/2,r/2+1,r,p);
	}
	else{
		long long rk=p-L+1;
		if (rk==1){
			return dg(l,r/2,r/2+1,r,r);
		}
		else{
			return dg(l,r/2,r/2+1,r,rk-1);
		}
	}
}
int main(){
	cin>>a+1>>n;
	m=strlen(a+1);
	l=m;
	while (l<n){
		l*=2;
	}//保证长度足够
	cout<<dg(1,l/2,l/2+1,l,n);//递归
}

正确结果
AC,完结撒花
祝你AC!

不要忘记点赞加关注哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值