递归与递推小结

问题 C: 【递归与递推】九连环

时间限制: 1 Sec 内存限制: 64 MB

题目描述
九连环是由九个彼此套接的圆环和一根横杆组成,九个环从左到右依次为l~9,每个环有两种状 态:1和0,1表示环在杆上,0表示环不在杆上。初始状态是九个环都在杆上,即:111111111,目标状态是九个环都不在杆上,即:000000000,由初始状态到目标状态的变化规则是:
(1)第一环为无论何时均可自由上下横行;
(2)第二只环只有在第一环为1时,才能自由上下;
(3)想要改变第n(n>2)个环的状态,需要先使第一到第(n-2)环均为下杆,且第n-1个环为上杆,而与第n+l个到第九环状态无关;
(4)每改变一个环,记为一步。
现在九连环由111111111变到000000000,求中间第i步的状态。
输入
仅包含一个整数i。
输出
仅包含中间第i步的状态。如果输入的步数大于实际变换所需的步数,则输出-1。
样例输入
【样例1】
2
【样例2】
500
样例输出
【样例1】
010111111
【样例2】
-1
脑子不够。。
题目大意:
给你步数,让你解九连环,看能解到什么状态,其中1实在九连环上,0是不在。
解题思路:

九连环的解法是,要解下第n个,就要n-2及其之前的都必须解下来,n-1在上面,这样才能解下第n个,同时剩下n-1个在上面。特别的,第一个可以自由上下。所以,就是很明显的递归。
递归函数:
参数——ring的编号。
终止条件:步数为0的时候。
递归过程,首先要判断第n-1个是否在上面,如果不在就要让他在上去;
然后遍历n-2之前的是否在上面,如果在,就让他们下来。

note:代码里0是没有解下来,1是已经解下来。

#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include <cstdio>
//#define local
using namespace std;

typedef unsigned long long ull;
typedef long long ll;

const int N = 2e4+5;
const int inf = 0x3f3f3f3f;
const int mod = 998244353;

int n;
int ring[10];
void dfs(int m){

   if(!n) return ;
   if(ring[m-1]) dfs(m-1);
   for(int i=m-2;i>=1;i--)
       if(!ring[i]) dfs(i);
   if(!n) return ;
   ring[m]=!ring[m];
   n--;
}
int main()
{
#ifdef local
   freopen("input.txt","r",stdin);
#endif
    scanf("%d",&n);
    memset(ring,0,sizeof(ring));
    for(int i=9;i>=1;i--)
        if(!ring[i]) dfs(i);
    if(n) printf("-1\n");
    else{
        for(int i=1;i<=9;i++)
        printf("%d",!ring[i]);
    }
    return 0;
}

问题D:2的幂次方

时间限制: 1 Sec 内存限制: 64 MB

题目描述
任何一个正整数都可以用2的幂次方表示。例如:
137 = 2 7 + 2 3 + 2 0 137=2^7+2^3+2^0 137=27+23+20
同时约定方次用括号来表示,即 a b a^b ab 可表示为 a ( b ) a(b) a(b)
由此可知, 137 137 137可表示为:
2 ( 7 ) + 2 ( 3 ) + 2 ( 0 ) 2(7)+2(3)+2(0) 2(7)+2(3)+2(0)
进一步: 7 = 2 2 + 2 + 2 0 ( 2 1 用 2 表 示 ) 3 = 2 + 2 0 7=2^2+2+2^0 (2^1用2表示) 3=2+2^0 7=22+2+20(212)3=2+20
所以最后 137 137 137可表示为:
2 ( 2 ( 2 ) + 2 + 2 ( 0 ) ) + 2 ( 2 + 2 ( 0 ) ) + 2 ( 0 ) 2(2(2)+2+2(0))+2(2+2(0))+2(0) 2(2(2)+2+2(0))+2(2+2(0))+2(0)
又如:
1315 = 2 1 0 + 2 8 + 2 5 + 2 + 2 0 1315=2^10 +2^8 +2^5 +2+2^0 1315=210+28+25+2+20
所以 1315 1315 1315最后可表示为:
2 ( 2 ( 2 + 2 ( 0 ) ) + 2 ) + 2 ( 2 ( 2 + 2 ( 0 ) ) ) + 2 ( 2 ( 2 ) + 2 ( 0 ) ) + 2 + 2 ( 0 ) 2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0) 2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

输入
一行,一个正整数(n≤20000)

输出
符合约定的n的0,2表示(在表示中不能有空格)

样例输入
137
样例输出
2(2(2)+2+2(0))+2(2+2(0))+2(0)

解题思路:

①看见别人有暴力打表解决问题的;
②递归的思路:
明确目的:求n的二次幂表示的各个指数,顺序是从高到低,之后将各个指数再进行“拆分操作”。
递归函数:
参数:当前的n值和递归的深度(2的指数)。
终止条件:n==1的时候
函数print(n,0)就是求n的“2的幂次方”表示,所以,递归调用print(n,0)就可以解决问题。(当然,当n<=2的时候,直接按格式输出就可以。)

#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include <cstdio>
//#define local
using namespace std;

typedef unsigned long long ull;
typedef long long ll;

const int N = 1e4+5;
const int inf = 0x3f3f3f3f;
const int mod = 998244353;

int n;
void print(int n,int deep){
    if(n==1){
        if(deep==0){
            printf("2(0)");
            return ;
        }
        if(deep==1){
            printf("2");
            return ;
        }
        if(deep==2){
            printf("2(2)");
            return ;
        }
        if(deep>2){
            printf("2(");
            print(deep,0);
            printf(")");
        }
    }
    else{
        print(n/2,deep+1);
        if(n&1){
            if(deep==0) printf("+2(0)");
            if(deep==1) printf("+2");
            if(deep==2) printf("+2(2)");
            if(deep>2){
                printf("+2(");
                print(deep,0);
                printf(")");
            }
        }
    }
}
int main()
{
#ifdef local
   freopen("input.txt","r",stdin);
#endif
    scanf("%d",&n);
    print(n,0);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值