大致题意:
递归地描述序列:设S(0)为3个字符的序列“mo o”。然后在较长的序列小号(ķ)通过取序列的拷贝获得小号(ķ -1),则“摩... O”与ķ 2 O公司,然后该序列的另一个拷贝小号(ķ -1 )。例如:
S(0)=“mo o”
S(1)=“moomooomo o”
S(2)=“moomooomoomoooomoomoo omo o”
...... 以此类推 可无限延长
预测这个字符串的第N个字符是“m”还是“o”
Input
Multiple test case. For each case:
* Line 1: A single integer N (1 ≤ N ≤ 109).
Output
For each case, output one line: The only line of output should contain a single character, which is either m or o.
Sample Input
11
Sample Output
m
#include <bits/stdc++.h> using namespace std; int a[35]; void constant() /*完整序列的规律可分为 a m a 三部分 即moomooomoo中,moo为a部分,mooo为m部分*/ { a[0]=0; a[1]=3; for(int i=2;i<35;i++) ///求出所有可能的有规律范围 a[i]=a[i-1]*2+i+2; } int find_area(int n) { int i=0; while(n>a[i++]); ///找到n所在的最小的有规律范围 return i-1; } int main() { constant(); int n; while(scanf("%d",&n)!=EOF) { int lie=find_area(n)-1; ///得到在n之前的有规律范围即前面的a部分 int flag=-1; while(flag<0) { n-=a[lie]; ///此时去掉前面的a部分 if(n==1) flag=1; else if(n<=lie+3) flag=0; //判断是否在m部分内 else { n-=lie+3; /*减去m部分,余下的后面的a部分同样可细分为a m a三部分, 则再次调用find_area()得到n所在的最小规律范围*/ lie=find_area(n)-1; } } ///继续循环直到缩小到m部分 修改flag值 跳出循环 if(flag==1) printf("m "); else if(flag==0) printf("o "); } return 0; }