您的位置:首页 > 其它

ACM解题报告四,五,六周

2018-01-14 21:22 169 查看
青蛙跳台阶
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 (numbe
4000
r == 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的正整数的所有因子之和等于它的本身,则称这个数是完数,比如6,28都是完数:6=1+2+3;28=1+2+4+7+14。

本题的任务是判断两个正整数之间完数的个数。
 
 
Input
输入数据包含多行,第一行是一个正整数n,表示测试实例的个数,然后就是n个测试实例,每个实例占一行,由两个正整数num1和num2组成,(1<num1,num2<10000)

 
 
Output
对于每组测试数据,请输出num1和num2之间(包括num1和num2)存在的完数个数。
 
 
Sample Input
2
2 5
5 7
 
 
Sample Output
0
1
算法:穷举法
将一个数的n的所有因子push到vector中,然后把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是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)数,比如6,28都是完数:6=1+2+3;28=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;
        }
    };
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: