Moo
题目描述
奶牛Bessie最近在学习字符串操作,它用如下的规则逐一的构造出新的字符串:
S(0) = “moo”
S(1) = S(0) + “m”+ “ooo” + S(0) = “moo” + “m” + “ooo” + “moo” = “moomooomoo”
S(2) = S(1) + “m” + “oooo” + S(1) = “moomooomoo” + “m” + “oooo” + “moomooomoo” = “moomooomoomoooomoomooomoo”
………
Bessie就这样产生字符串,直到最后产生的那个字符串长度不小于读入的整数N才停止。
通过上面观察,可以发现第k个字符串是由:第k-1个字符串 + “m” + (k+2个o) + 第k-1个字符串连接起来的。
现在的问题是:给出一个整数N (1 <= N <= 10^9),问第N个字符是字母‘m’还是‘o’?
输入格式
一个整数N。
输出格式
一个字符,m或者o
输入 #1
11
输出 #1
m
第 i 个字符串的长度为 a[i]=2*a[i-1]+i+3; 先预处理出长度为 n 的字符串是第几个字符串;也就是说要连接几次;
解法一:
根据要连接几次,然后把字符串连接起来,求n的位置的字符;
但是只有80分,因为n的范围为1e9;爆了空间;
#include<bits/stdc++.h>
using namespace std;
int n;
int a[100000];
string dfs(int p){
string s="";
if(p==0){
return "moo";
}
string ss="";
for(int i=1;i<=p+2;i++) ss+="o";
string b=dfs(p-1);
return b+"m"+ss+b;
}
int main(){
scanf("%d",&n);
a[0]=3;
int ans;
for(int i=1;;i++){
a[i]=2*a[i-1]+i+3;
if(a[i]>=n){
ans=i;
break;
}
}
string s=dfs(ans);
cout<<s[n-1]<<endl;
return 0;
}
解法二:
看代码模拟一下,应该就可以了吧;
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
#define N 500100
#define M 2000010
using namespace std;
int n;
int a[100000];
void dfs(int p,int q){//p为剩余的长度,q为第几个字符串
while(a[q-1]>p) q--;
if(p==a[q-1]+1){
cout<<"m"<<endl;
return;
}
else if(p<=a[q-1]+q+3){
cout<<"o"<<endl;
return;
}
dfs(p-a[q-1]-q-3,q-1);
}
int main(){
scanf("%d",&n);
a[0]=3;
int ans;
for(int i=1;;i++){
a[i]=2*a[i-1]+i+3;
if(a[i]>=n){
ans=i;
break;
}
}
dfs(n,ans);
return 0;
}