洛谷P1885 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
说明/提示
样例解释:
由题目所知:字符串S(0)是moo, 现在要求第11个字符,显然字符串S(0)不够长;
同样S(1)的长度是10,也不够长;S(2)的长度是25,够长了,S(2)的第11个字符是m,所以答案就输出m。
分治黄题(一开始啥也不会QwQ)
一开始看到这个题没去想解决方法
先去想的是这个字符串的长度
于是在这里卡关了...
建议递推重造
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<string> #include<cstring> using namespace std; int main() { int n; long long a[1000]; memset(a,0,sizeof(a)); a[0]=0; a[1]=3; a[2]=10; a[3]=25; cin>>n; for(int i=1;i<=1000;i++) a[i]=a[i-1]*2+i+2; cout<<a[n]; } //求s(n)字符串的长度
好了认真讲下思路
首先需要判断第n个字母在哪段字符串里
写个查找函数
int start(int p) { int now,i=1; t[0] = 0; while(1) { t[i]=2*t[i-1]+(i+2);求字符串长度 if(t[i]>=p)//p在s(i)这一段串里就停下 {now=i;break;} i++;//不行就找下个s(i+1) } return now;//返回目前是S(几) }
然后查找完以后准备分治判断
先写一波骨架
#include <iostream> #include<cstring> #include<cstdio> #include<algorithm> #define Size 100005//最大字符串组数 using namespace std; typedef long long type; type n; string str;//定义字符串 int t[Size];//定义字符串每组的长度 int start(int p);//判断函数 void solve(int q,int n);//处理函数 int main() { int cnt = 0; cin>>n; cnt=start(n);//先判断 solve(cnt,n);//再处理 return 0; }
再写个处理函数
void solve(int q,int n)//分别进入刚才查找出的那段字符串的序号和n { while(t[q-1]>n) q--; //从查找出的n所在的字符串的上一个字符串末尾进行查找 if(n==t[q-1]+1)//如果n是该字符串的第一个字符 { printf("m\n"); //输出m return ; } else if(n<=t[q-1]+q+2)//开始第二个直到末尾字符都为o { printf("o\n"); return ; } solve(q-1,n-(t[q-1]+q+2)); //向内继续查找 }
则总代码为
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #define Size 100005 using namespace std; typedef long long type; type n; string str; int t[Size]; int start(int p); void solve(int q,int n); int main() { int cnt = 0; cin>>n; cnt=start(n); solve(cnt,n); return 0; } int start(int p) { int now,i=1; t[0] = 0; while(1) { t[i]=2*t[i-1]+(i+2); if(t[i]>=p) {now=i;break;} i++; } return now; } void solve(int q,int n) { while(t[q-1] > n) q--; if(n == t[q-1]+1) { printf("m\n"); return ; }else if(n <= t[q-1]+q+2) { printf("o\n"); return ; } solve(q-1,n-(t[q-1]+q+2)); }
End