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;
}
};
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;
}
};
相关文章推荐
- 2012 ACM/ICPC Asia Regional Changchun Online 解题报告
- YT05-动态归划求解课后题目-1003—免费馅饼 -(6.21日-烟台大学ACM预备队解题报告)
- Pku acm 1157 LITTLE SHOP OF FLOWERS 动态规划题目解题报告(十四)
- ACM POJ 2245Lotto解题报告
- acm解题报告 HDU 2141 Can you find it?
- Pku acm 2371 Questions and answers 排序算法解题报告(三)----二叉查找数(BST)排序
- 【Jason's_ACM_解题报告】Assemble
- 【Jason's_ACM_解题报告】Jurassic Remains
- 【Jason's_ACM_解题报告】The Blocks Problem
- 【Jason's_ACM_解题报告】Not so Mobile
- 【ACM解题报告】A+B Coming
- 【ACM菜逼解题报告】Ananagrams
- 【Jason's_ACM_解题报告】The Morning after Halloween
- POJ1062 昂贵的聘礼 ACM解题报告(dijkstra+枚举)
- 2014 ACM/ICPC 西安赛区网络赛解题报告汇总
- ACM--HDOJ2502解题报告
- 北大ACM试题分类 - 实时更新我所有的解题报告链接
- 河南省第七届ACM大学生程序设计竞赛 解题报告
- YT02-简单数学课堂题-1003 The area -(5.31日-烟台大学ACM预备队解题报告)
- 【Jason's_ACM_解题报告】Help is needed for Dexter