zoukankan      html  css  js  c++  java
  • 【校内模拟】数列

    ![](https://img2018.cnblogs.com/blog/1340330/201810/1340330-20181019080446315-1580382296.png)

    这是一套模拟题的(T1)

    看完题我首先想到的是找规律

    我人工推了几项后发现了一点鬼畜的规律,然后就打了代码

    直到爆零之后发现它不是一道找规律的题

    看完题解我感觉无(F**K)

    为什么(T1)如此毒瘤(其实是我太菜)

    题解:

    显然根据斐波那契数列,第(50)个字符串的长度一定远超过了(2^{31})的范围

    我们不妨将大于(50)(n) 奇数看作(49),偶数看作(48)

    我们可以将前(20)个字符串预处理出来

    (nleq 20)时直接输出答案

    否则设一个函数(solve(n,l,r))递归到(n-2)(n-1)

    (l)(r)的递归需要知道第(n-2)个字符串的长度

    预处理斐波那契数列即可

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define LL long long
    int n,l,r;
    LL f[50];
    string s[21];
    void solve(int t,int x,int y){
    	if(x>y||x>=f[t]) return;
    	if(t<=20){
    		for(int i=x;i<=y;++i)
    			putchar(s[t][i]);
    		return;
    	}
    	if(f[t-2]-1>=y)
    		solve(t-2,x,y);
    	else if(f[t-2]<=x)
    			solve(t-1,x-f[t-2],y-f[t-2]);
    	else {
    		solve(t-2,x,f[t-2]-1);
    		solve(t-1,0,y-f[t-2]);
    	}
    }
    int main()
    {
    	freopen("sequence.in","r",stdin);
    	freopen("sequence.out","w",stdout);
    	scanf("%d%d%d",&n,&l,&r);
    	if(n>=50)
    		if(n%2) n=49;
    		else n=48;
    	f[0]=1;
    	f[1]=1;
    	for(int i=2;i<=n;++i)
    		f[i]=f[i-1]+f[i-2];
    	s[0]="0";
    	s[1]="1";
    	for(int i=2;i<=20;++i)
    		s[i]=s[i-2]+s[i-1];
    	if(n<=20){
    		for(int i=l;i<=r;++i)
    			putchar(s[n][i]);
    		puts("");
    		return 0;
    	}
    	solve(n,l,r);
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    HDU 6071
    HDU 6073
    HDU 2124 Repair the Wall(贪心)
    HDU 2037 今年暑假不AC(贪心)
    HDU 1257 最少拦截系统(贪心)
    HDU 1789 Doing Homework again(贪心)
    HDU 1009 FatMouse' Trade(贪心)
    HDU 2216 Game III(BFS)
    HDU 1509 Windows Message Queue(队列)
    HDU 1081 To The Max(动态规划)
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/9814351.html
Copyright © 2011-2022 走看看