HDOJ 2041-2050(递归专题)

2041超级楼梯

Problem Description
有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?
 
Input
输入数据首先包含一个整数N,表示测试实例的个数,然后是N行数据,每行包含一个整数M(1<=M<=40),表示楼梯的级数。
 
Output
对于每个测试实例,请输出不同走法的数量
 
Sample Input
2
2
3
 
Sample Output
1
2
 
递归
#include <bits/stdc++.h>
using namespace std;
int getStire(int m)
{

    if (m > 2)
        return 1 + getStire(m - 2) + 1 + getStire(m-3);
    else if (m == 2)
        return 1;
    else
        return 0;
}
int main()
{
    int n,s;
    scanf("%d",&n);
    int i;
    for(i=0;i<n;i++)
    {
        scanf("%d",&s);
        printf("%d\n",getStire(s));
    }
}

 

 
 
 

2042不容易系列之二

Problem Description
你活的不容易,我活的不容易,他活的也不容易。不过,如果你看了下面的故事,就会知道,有位老汉比你还不容易。

重庆市郊黄泥板村的徐老汉(大号徐东海,简称XDH)这两年辛辛苦苦养了不少羊,到了今年夏天,由于众所周知的高温干旱,实在没办法解决牲畜的饮水问题,就决定把这些羊都赶到集市去卖。从黄泥板村到交易地点要经过N个收费站,按说这收费站和徐老汉没什么关系,但是事实却令徐老汉欲哭无泪:
(镜头回放)
近景:老汉,一群羊
远景:公路,收费站

......

收费员(彬彬有礼+职业微笑):“老同志,请交过路费!”
徐老汉(愕然,反应迟钝状):“锅,锅,锅,锅-炉-费?我家不烧锅炉呀?”
收费员(职业微笑依然):“老同志,我说的是过-路-费,就是你的羊要过这个路口必须交费,understand?”
徐老汉(近镜头10秒,嘴巴张开):“我-我-我知道汽车过路要收费,这羊也要收费呀?”
收费员(居高临下+不解状):“老同志,你怎么就不明白呢,那么我问你,汽车几个轮子?”
徐老汉(稍放松):“这个我知道,今天在家里我孙子还问我这个问题,4个!”
收费员(生气,站起):“嘿!老头,你还骂人不带脏字,既然知道汽车四个轮子,难道就不知道这羊有几条腿吗?!”
徐老汉(尴尬,依然不解状):“也,也,也是4个呀,这有关系吗?”
收费员(生气,站起):“怎么没关系!我们头说了,只要是4条腿的都要收费!”

......

(画外音)
由于徐老汉没钱,收费员就将他的羊拿走一半,看到老汉泪水涟涟,犹豫了一下,又还给老汉一只。巧合的是,后面每过一个收费站,都是拿走当时羊的一半,然后退还一只,等到老汉到达市场,就只剩下3只羊了。
你,当代有良知的青年,能帮忙算一下老汉最初有多少只羊吗?
 
Input
输入数据第一行是一个整数N,下面由N行组成,每行包含一个整数a(0<a<=30),表示收费站的数量。
 
Output
对于每个测试实例,请输出最初的羊的数量,每个测试实例的输出占一行。
 
Sample Input
2
1
2
 
Sample Output
4
6
 
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,i,j;
    int a,s;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d",&a);
        s=3;
        for(j=0;j<a;j++)
        {
            s=(s-1)*2;

        }
        printf("%d\n",s);
    }
}

 

 
 

2043密码

Problem Description
网上流传一句话:"常在网上飘啊,哪能不挨刀啊~"。其实要想能安安心心地上网其实也不难,学点安全知识就可以。
首先,我们就要设置一个安全的密码。那什么样的密码才叫安全的呢?一般来说一个比较安全的密码至少应该满足下面两个条件:

(1).密码长度大于等于8,且不要超过16。
(2).密码中的字符应该来自下面“字符类别”中四组中的至少三组。
这四个字符类别分别为:
1.大写字母:A,B,C...Z;
2.小写字母:a,b,c...z;
3.数字:0,1,2...9;
4.特殊符号:~,!,@,#,$,%,^;
给你一个密码,你的任务就是判断它是不是一个安全的密码。
 
Input
输入数据第一行包含一个数M,接下有M行,每行一个密码(长度最大可能为50),密码仅包括上面的四类字符。
 
Output
对于每个测试实例,判断这个密码是不是一个安全的密码,是的话输出YES,否则输出NO。
 
Sample Input
3
a1b2c3d4
Linle@ACM
^~^@^@!%
 
Sample Output
NO
YES
NO
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    string s;
    int i, j;
    scanf("%d", &n);
    getchar();
    for (i = 0; i < n; i++)
    {
        int flag[4] = {0, 0, 0, 0};
        getline(cin, s);
        if (s.size() < 8)
        {
            printf("NO\n");
            continue;
        }
        for (j = 0; j < s.size(); j++)
        {
            if (s[j] >= 'a' && s[j] <= 'z')
                flag[0] = 1;
            else if (s[j] >= 'A' && s[j] <= 'Z')
                flag[1] = 1;
            else if (s[j] >= '0' && s[j] <= '9')
                flag[2] = 1;
            else if (s[j] == '~' || s[j] == '!' || s[j] == '@' || s[j] == '#' || s[j] == '$' || s[j] == '%' || s[j] == '^')
                flag[3] = 1;
        }
        if ((flag[0] + flag[1] + flag[2] + flag[3]) >= 3)
            printf("YES\n");
        else
            printf("NO\n");
    }
}

 

 
 
 
 

2044一只小蜜蜂

Problem Description
有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。
其中,蜂房的结构如下所示。
 
Input
输入数据的第一行是一个整数N,表示测试实例的个数,然后是N 行数据,每行包含两个整数a和b(0<a<b<50)。
 
Output
对于每个测试实例,请输出蜜蜂从蜂房a爬到蜂房b的可能路线数,每个实例的输出占一行。

Sample Input
2
1 2
3 6
 
Sample Output
1
3
递归
#include <bits/stdc++.h>
using namespace std;
int getBeeRoad(int a, int b)
{
    if (a == b)
        return 0;
    if (b - a == 1)
        return 1;
    if (b - a == 2)
        return 2;
    return getBeeRoad(a + 1, b) + getBeeRoad(a + 2, b);
}
int main()
{
    int n;
    int a, b;
    int i, j;
    int road;
    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        scanf("%d %d", &a, &b);
        printf("%d\n", getBeeRoad(a, b));
    }
}

 


2045不容易系列之(3)—— LELE的RPG难题

Problem Description
人称“AC女之杀手”的超级偶像LELE最近忽然玩起了深沉,这可急坏了众多“Cole”(LELE的粉丝,即"可乐"),经过多方打探,某资深Cole终于知道了原因,原来,LELE最近研究起了著名的RPG难题:
有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法.
以上就是著名的RPG难题.
如果你是Cole,我想你一定会想尽办法帮助LELE解决这个问题的;如果不是,看在众多漂亮的痛不欲生的Cole女的面子上,你也不会袖手旁观吧?

Input
输入数据包含多个测试实例,每个测试实例占一行,由一个整数N组成,(0<n<=50)。
 
Output
对于每个测试实例,请输出全部的满足要求的涂法,每个实例的输出占一行。

Sample Input
1
2
 
Sample Output
3
6
以为是递归,原来要递推:

f(1)=3,f(2)=6,f(3)=6,f(4)=18

f(n)=f(n-1)+2*f(n-2)

#include<stdio.h>
long long a[100];
int main(void)
{
    
    a[1]=3;
    a[2]=6;
    a[3]=6;
    int n;
    for(int i=4;i<100;i++)
    {
        a[i]=a[i-1]+2*a[i-2];
    }
    while(scanf("%d",&n)!=EOF)
    {
        printf("%lld\n",a[n]);
    }
    return 0;
}

 

 
 

2046骨牌铺方格

Problem Description
在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出铺放方案的总数.
例如n=3时,为2× 3方格,骨牌的铺放方案有三种,如下图:
Input
输入数据由多行组成,每行包含一个整数n,表示该测试实例的长方形方格的规格是2×n (0<n<=50)。

Output
对于每个测试实例,请输出铺放方案的总数,每个实例的输出占一行。
 
Sample Input
1
3
2

Sample Output
1
3
2
 
#include <bits/stdc++.h>
using namespace std;
int getBlocks(int n)
{
    if (n == 1)
        return 1;
    if (n == 2)
        return 2;
    if (n == 3)
        return 3;
    return getBlocks(n-1)+getBlocks(n-2);
}
int main()
{
    int n;
    scanf("%d",&n);
    int i;
    int x;
    for(i=0;i<n;i++)
    {
        scanf("%d",&x);
        printf("%d",getBlocks(x));

    }
}

 

 

2047阿牛的EOF牛肉串

Problem Description
今年的ACM暑期集训队一共有18人,分为6支队伍。其中有一个叫做EOF的队伍,由04级的阿牛、XC以及05级的COY组成。在共同的集训生活中,大家建立了深厚的友谊,阿牛准备做点什么来纪念这段激情燃烧的岁月,想了一想,阿牛从家里拿来了一块上等的牛肉干,准备在上面刻下一个长度为n的只由"E" "O" "F"三种字符组成的字符串(可以只有其中一种或两种字符,但绝对不能有其他字符),阿牛同时禁止在串中出现O相邻的情况,他认为,"OO"看起来就像发怒的眼睛,效果不好。

你,NEW ACMer,EOF的崇拜者,能帮阿牛算一下一共有多少种满足要求的不同的字符串吗?

PS: 阿牛还有一个小秘密,就是准备把这个刻有 EOF的牛肉干,作为神秘礼物献给杭电五十周年校庆,可以想象,当校长接过这块牛肉干的时候该有多高兴!这里,请允许我代表杭电的ACMer向阿牛表示感谢!

再次感谢!
 
Input
输入数据包含多个测试实例,每个测试实例占一行,由一个整数n组成,(0<n<40)。

Output
对于每个测试实例,请输出全部的满足要求的涂法,每个实例的输出占一行。
 
Sample Input
1
2
 
Sample Output
3
8
#include <bits/stdc++.h>
using namespace std;
int getEOF(int n, char a)
{
    if (n == 1)
        return 1;
    if (a == 'E')
        return getEOF(n - 1, 'E') + getEOF(n - 1, 'O') + getEOF(n - 1, 'F');
    if (a == 'F')
        return getEOF(n - 1, 'E') + getEOF(n - 1, 'O') + getEOF(n - 1, 'F');
    if (a == 'O')
        return getEOF(n - 1, 'E') + getEOF(n - 1, 'F');
}
int main()
{
    int i;
    int x;
    while(scanf("%d",&x)!=EOF)
    {
        printf("%d\n",getEOF(x,'E')+getEOF(x,'F')+getEOF(x,'O'));

    }
}

 

 
 
 

 2048神、上帝以及老天爷

Problem Description
HDU 2006'10 ACM contest的颁奖晚会隆重开始了!
为了活跃气氛,组织者举行了一个别开生面、奖品丰厚的抽奖活动,这个活动的具体要求是这样的:

首先,所有参加晚会的人员都将一张写有自己名字的字条放入抽奖箱中;
然后,待所有字条加入完毕,每人从箱中取一个字条;
最后,如果取得的字条上写的就是自己的名字,那么“恭喜你,中奖了!”

大家可以想象一下当时的气氛之热烈,毕竟中奖者的奖品是大家梦寐以求的Twins签名照呀!不过,正如所有试图设计的喜剧往往以悲剧结尾,这次抽奖活动最后竟然没有一个人中奖!

我的神、上帝以及老天爷呀,怎么会这样呢?

不过,先不要激动,现在问题来了,你能计算一下发生这种情况的概率吗?

不会算?难道你也想以悲剧结尾?!
 
Input
输入数据的第一行是一个整数C,表示测试实例的个数,然后是C 行数据,每行包含一个整数n(1<n<=20),表示参加抽奖的人数。

Output
对于每个测试实例,请输出发生这种情况的百分比,每个实例的输出占一行, 结果保留两位小数(四舍五入),具体格式请参照sample output。

Sample Input
1
2
 
Sample Output
50.00%
翻译:n个人将写有自己名字的纸条放入纸箱,再随机抽取一个纸条 ,所有人抽到的纸条与自身均不匹配的概率是多大
这个问题推广一下,就是错排问题,是组合数学中的问题之一。
考虑一个有n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排。 n个元素的错排数记为D(n)。 研究一个排列错排个数的问题,叫做错排问题或称为更列问题。
当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用D(n)表示,那么D(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推.
第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法;
第二步,放编号为k的元素,这时有两种情况:
      ①把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有D(n-2)种方法;
      ②第k个元素不把它放到位置n,这时,对于这n-1个元素,有D(n-1)种方法;

      D(n) = (n-1) [D(n-2) + D(n-1)]
      特殊地,D(1) = 0, D(2) = 1.
#include <bits/stdc++.h>
using namespace std;
double F[21];
int main()
{
    int n, t;
    F[1] = 0;
    F[2] = 1;
    for (int i = 3; i < 21; i++)
    {
        F[i] = (i - 1) * (F[i - 1] + F[i - 2]);
    }

    cin >> t;
    while (t--)
    {
        cin >> n;
        double t = 1;
        for (int i = 1; i <= n; i++)
        {
            t *= i;
        }
        double ans = F[n] / t;
        printf("%.2f%%\n", ans * 100); // 注意这里要输出%要写两个%
    }

    return 0;
}

 

 
 
 

2049不容易系列之(4)——考新郎

Problem Description
国庆期间,省城HZ刚刚举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做"考新郎",具体的操作是这样的:


首先,给每位新娘打扮得几乎一模一样,并盖上大大的红盖头随机坐成一排;
然后,让各位新郎寻找自己的新娘.每人只准找一个,并且不允许多人找一个.
最后,揭开盖头,如果找错了对象就要当众跪搓衣板...
看来做新郎也不是容易的事情...

假设一共有N对新婚夫妇,其中有M个新郎找错了新娘,求发生这种情况一共有多少种可能.

Input
输入数据的第一行是一个整数C,表示测试实例的个数,然后是C行数据,每行包含两个整数N和M(1<M<=N<=20)。
 
Output
对于每个测试实例,请输出一共有多少种发生这种情况的可能,每个实例的输出占一行。
 
Sample Input
2
2 2
3 2
 
Sample Output
1
3
 

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll c[25][25],f[25]={0,0,1};

void Init(){
    for(int n=0;n<=20;n++)//Cn 0和Cn n都置为1
        c[n][0]=c[n][n]=1;
    for(int n=1;n<=20;n++)//Cn 1到Cn n-1由递推公式求得
        for(int m=1;m<n;m++)
            c[n][m]=c[n-1][m-1]+c[n-1][m];
    for(int i=3;i<=20;i++)//规模为i的错排的递推
        f[i]=(i-1)*(f[i-1]+f[i-2]);
}

int main()
{
    Init();//初始化组合、错排表
    ll t,n,m;cin>>t;
    while(t--){
        cin>>n>>m;
        cout<<c[n][m]*f[m]<<endl;
    }
    return 0;
}

 

 

2050折线分割平面

Problem Description
我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目。比如,一条折线可以将平面分成两部分,两条折线最多可以将平面分成7部分,具体如下所示。
Input
输入数据的第一行是一个整数C,表示测试实例的个数,然后是C 行数据,每行包含一个整数n(0<n<=10000),表示折线的数量。
 
Output
对于每个测试实例,请输出平面的最大分割数,每个实例的输出占一行。

Sample Input
2
1
2
 
Sample Output
2
7
 
 
 
 
 
 
posted @ 2023-03-02 20:12  EleclouD  阅读(46)  评论(0编辑  收藏  举报