ACM解题报告四,五,六周

青蛙跳台阶

Problem Description

一只青蛙一次可以跳上1级台阶,也可以跳上2……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

算法 :动态规划 也可以用递归做,递归和dp的区别在于空间和时间的取舍

分析:

寻找递推公式

N级台阶 第一步的跳法有n

第一步跳1级 那么剩下(n-1)级 ,跳法:f(n-1)

第一步跳2级 那么剩下(n-2)级   跳法:f(n-2)

第一步跳n级,那么剩下(n-n)级  跳法:f(n-n)

所以f(n)=f(n-1)+f(n-2)+…+f(n-n)

化简:

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

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

(1)-(2)得  f(n)-f(n-1)=f(n-1);  f(n)=2*f(n-1) (n>2)

f(0)=1

f(1)=1

f(2)=2

代码:

 

classSolution {

    public:

        intjumpFloorII(intnumber) {

            int *fn = newint[number+1];

            fn[0] = 1;

            fn[1] = 1;

            if (number == 1 || number == 0)

                return1;

            for (inti = 2; i <= number; i++) {

                fn[i] = 2 * fn[i - 1];

            }

            returnfn[number];

        }

    };

 

完数

Time Limit: 2000/1000 MS(Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 30492    Accepted Submission(s): 11486


Problem Description

完数的定义:如果一个大于1的正整数的所有因子之和等于它的本身,则称这个数是完数,比如628都是完数:6=1+2+328=1+2+4+7+14

本题的任务是判断两个正整数之间完数的个数。

 

 

Input

输入数据包含多行,第一行是一个正整数n,表示测试实例的个数,然后就是n个测试实例,每个实例占一行,由两个正整数num1num2组成,(1<num1,num2<10000)

 

 

Output

对于每组测试数据,请输出num1num2之间(包括num1num2)存在的完数个数。

 

 

Sample Input

2

2 5

5 7

 

 

Sample Output

0

1

算法:穷举法

将一个数的n的所有因子pushvector中,然后把vector中元素相加,判断是否是完数。

代码:

#include <stdio.h>

#include <iostream>

#include <algorithm>

#include <vector>

usingnamespacestd;

intjudge(intn) {

    if (n == 0) {

        return0;

    }

    vector<int> a;

    for (inti = 1; i < n; i++) {

        if ((n%i) == 0) {

            a.push_back(i);

        }

    }

    intresult = 0;

    for (inti = 0; i < a.size(); i++) {

        result += a[i];

    }

    if (result == n)

        return1;

    return0;

}

intmain() {

    intn;

    intnum1, num2;

    scanf("%d", &n);

    while (n--) {

        intresult = 0;

        scanf("%d%d", &num1, &num2);

        inttemp;

        if (num1 > num2) {

            temp = num2;

            num2 = num1;

            num1 = temp;

        }

        for (inti = num1; i <= num2; i++) {

            if (judge(i) == 1) {

                result++;

            }

        }

        printf("%d\n", result);

    }

    

    return0;

}

栈的压入弹出序列




Problem Description

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列45,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)数,比如628都是完数:6=1+2+328=1+2+4+7+14

本题的任务是判断两个正整数之间完数的个数。

 

Input

两个序列

Output

 True orfalse

Sample Input

[1,2,3,4,5][5,4,3,2,1]

Sample Output

True

Sample Input

[1,2,3,4,5][4,3,5,1,2]

Sample Output

False
算法:

设置一个辅助栈vec

遍历输入序列

将输入序列压入辅助栈,如果辅助栈栈顶元素和输出序列当前元素相同,则出栈,同时指针指向输出序列下一个元素

例如 输入序列[1,2,3,4,5]

        输出序列[5,4,3,2,1]

1入栈,不相同

2入栈,不相同                  

3入栈,不相同

4入栈,不相同

5入栈,相同出栈 此时指针指向4,出栈..指针指向3,出栈…

最后判断辅助栈是否为空

代码:

classSolution {

    public:

        boolIsPopOrder(vector<int> pushV, vector<int> popV) {

            vector<int> vec;

            intj = 0;

            for (inti = 0; i < pushV.size(); i++) {

                vec.push_back(pushV[i]);

                while (vec.size()&&vec[vec.size() - 1] == popV[j]) {

                    vec.pop_back();

                    j++;

                }

            }

            returnvec.size() == 0;

        }

    };

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值