总时间限制:
1000ms
内存限制:
65536kB
描述
逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4。本题求解逆波兰表达式的值,其中运算符包括+ - * /四个。
输入
输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数。
输出
输出为一行,表达式的值。
可直接用printf("%f\n", v)输出表达式的值v。
样例输入
* + 11.0 12.0 + 24.0 35.0
样例输出
1357.000000
因为是逆波兰表达式,所以我们是从后往前算的,遇到一个计算符号,就计算这个计算符后面两个数字的值,
如何转化为递归呢?
#include
#include
using namespace std;
double exp(){
char s[20];
cin >> s;
switch(s[0]){
case '+' :return exp() + exp();
case '-' :return exp() - exp();
case '*' :return exp() * exp();
case '/' :return exp() / exp();
default : return atof(s); //2atof(将字串转换成浮点型数)
break;
}
}
int main(){
printf("%f", exp());
return 0;
}
总时间限制:
1000ms
内存限制:
65536kB
描述
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列。
输入
输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。
输出
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:
已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存在p (1 <= p <= k),使得
s1 = t1, s2 = t2, ..., sp - 1 = tp - 1, sp < tp成立。
样例输入
abc
样例输出
abc
acb
bac
bca
cab
cba
全排列递归
我们外+一个字符串数组了来保存我们排列的结果,
我们从0开始排列,先一S[0] 作为第一个,然后从 后面选,每选一个就标记一下,避免重选,然后计算现在排列了几个,当我们回来时要把标记去掉,因为这种情况已经排完了。不影响下次排列。
退出边界是全部字符都被排列到 t[ ] 中,输出即可。
#include
#include
#include
using namespace std;
string s;
int len;
bool vis[100];
string t;
void quanpai(int index){
if(index == len){
for(int i = 0; i < len; i++){
cout << t[i];
}
cout << endl;
return ;
}
for(int i = 0; i < len; i++){
if(vis[i] == 0)
{
t[index] = s[i];
vis[i] = 1;
quanpai(index + 1);
vis[i] = 0;
}
}
}
int main(){
cin >> s;
len = s.length();
memset(vis, 0, sizeof(vis));
quanpai(0);
return 0;
}
总时间限制:
1000ms
内存限制:
65536kB
描述
给出一个正整数a,要求分解成若干个正整数的乘积,即a = a1 * a2 * a3 * ... * an,并且1 < a1 <= a2 <= a3 <= ... <= an,问这样的分解的种数有多少。注意到a = a也是一种分解。
输入
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数a (1 < a < 32768)
输出
n行,每行输出对应一个输入。输出应是一个正整数,指明满足要求的分解的种数
样例输入
2
2
20
样例输出
1
4
思路:
给你一个数让你求出所有因数相乘的情况
比如20
1) 20 * 1
2)2 * 2 * 5
3)2 * 10
4)4 * 5
共 4 种
我们可以从2 开始,然后每次去看 2 * x = n有多少种情况 然后去看 3 一直到 n,
这样我们就可以写出递归程序了,退出边界就是n = 1。
#include
#include
#include
using namespace std;
int DFS(int n, int m){
int count = 0;
if(n == 1)
return 1;
for(int i = m; i <= n; i++){
if(n % i == 0)
count += DFS(n/i, i);
}
return count;
}
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
cout << DFS(n,2) << endl;
}
return 0;
}
总时间限制:
1000ms
内存限制:
65536kB
描述
菲波那契数列是指这样的数列: 数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和。
给出一个正整数a,要求菲波那契数列中第a个数是多少。
输入
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数a(1 <= a <= 20)
输出
输出有n行,每行输出对应一个输入。输出应是一个正整数,为菲波那契数列中第a个数的大小样例输入
4
5
2
19
1
样例输出
5
1
4181
1
解题思路:
你要算 f(n) 的值,你就需要算 f ( n -2 ) 和f(n-1) 的值,这样递归的条件就出来了 然后你再去推下边界。
#include
#include
#include
using namespace std;
int DFS(int n){
if(n == 1)
return 1;
if(n == 2)
return 1;
else
return DFS(n-1) + DFS(n-2);
}
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
cout << DFS(n) << endl;
}
return 0;
}
总时间限制:
3000ms
内存限制:
65536kB
描述
Pell数列a1, a2, a3, ...的定义是这样的,a1 = 1, a2 = 2, ... , an = 2 * an − 1 + an - 2 (n > 2)。
给出一个正整数k,要求Pell数列的第k项模上32767是多少。
输入
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数k (1 ≤ k < 1000000)。
输出
n行,每行输出对应一个输入。输出应是一个非负整数。样例输入
2
1
8
样例输出
1
408
解题思路:给上题一样,有递归方程和条件.但是单纯的搜索会超时,你需要一个数组来保存算过的值,更可以减少重复搜索。
#include
#include
#include
using namespace std;
long long a[1000005];
long long DFS(int n){
if(a[n] != 0)
return a[n];
else
return a[n] = (DFS(n-1) * 2 + DFS(n-2)) % 32767;
}
int main(){
int t;
cin >> t;
a[1] = 1;
a[2] = 2;
a[0] = 1;
while(t--){
long long n;
cin >> n;
cout << DFS(n) << endl;
}
return 0;
}
总时间限制:
1000ms
内存限制:
65536kB
描述
树老师爬楼梯,他可以每次走1级或者2级,输入楼梯的级数,求不同的走法数
例如:楼梯一共有3级,他可以每次都走一级,或者第一次走一级,第二次走两级
也可以第一次走两级,第二次走一级,一共3种方法。
输入
输入包含若干行,每行包含一个正整数N,代表楼梯级数,1 <= N <= 30
输出
不同的走法数,每一行输入对应一行输出
样例输入
5
8
10
样例输出
8
34
89
解题思路:
我们 我们想一下现在我们在第n 个台阶,然后向下走有2种方式,要么向下1 步,要么向下2步
这就可以递归了
#include
#include
#include
using namespace std;
long long a[1000005];
long long DFS(int n){
if(a[n] != 0)
return a[n];
else
return a[n] = DFS(n-1) + DFS(n-2);
}
int main(){
a[1] = 1;
a[2] = 2;
long long n;
while(cin >> n){
cout << DFS(n) << endl;
}
return 0;
}
总时间限制:
1000ms
内存限制:
65536kB
描述
约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到中间的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面。
这是一个著名的问题,几乎所有的教材上都有这个问题。由于条件是一次只能移动一个盘,且不允许大盘放在小盘上面,所以64个盘的移动次数是:18,446,744,073,709,551,615
这是一个天文数字,若每一微秒可能计算(并不输出)一次移动,那么也需要几乎一百万年。我们仅能找出问题的解决方法并解决较小N值时的汉诺塔,但很难用计算机解决64层的汉诺塔。
假定圆盘从小到大编号为1, 2, ...
输入
输入为一个整数后面跟三个单字符字符串。
整数为盘子的数目,后三个字符表示三个杆子的编号。
输出
输出每一步移动盘子的记录。一次移动一行。
每次移动的记录为例如 a->3->b 的形式,即把编号为3的盘子从a杆移至b杆。
样例输入
2 a b c
样例输出
a->1->c
a->2->b
c->1->b
解题思路:
这个题是把所有的盘子移动到中间的盘子中
#include
#include
#include
using namespace std;
void DFS(int n, char a, char b, char c){
if(n == 1)
cout << a << "->" << n << "->" << b << endl; //只有一个盘子把他从A移动到 B
else{
DFS(n - 1, a, c, b); //把n-1个盘子,从A,经过B移动到C
cout << a << "->" << n << "->" << b << endl; //把最后一个盘子从A 移动到 B
DFS(n - 1, c, b, a); //再把 n - 1个盘子从C经过A移动到B
}
}
int main(){
int t;
cin >> t;
char a, b, c;
cin >> a >> b >> c;
DFS(t, a, b, c);
return 0;
}
总时间限制:
1000ms
内存限制:
65536kB
描述
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
输入
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
输出
对输入的每组数据M和N,用一行输出相应的K。
样例输入
1
7 3
样例输出
8
、解题思路:
你有n个苹果m个盘子,然后你进行放苹果的游戏,你放的话是有2种情况的是把,
1)有盘子空着
2)没有盘子空着
有盘子空着时 就是 n 个 苹果放到m - 1 个盘子中去
没有盘子空着时就是 n - m 个苹果再放到m 个盘子中去。
然后呢 当 n < m 时 是不是 盘子比苹果多,因为盘子是一样的,所以我们这个问题就转化成了 n 个苹果放到n 个盘子里了。
#include
#include
#include
using namespace std;
long long DFS(int n, int m){
if(m == 0) //没有盘子
return 0; //没有方法
if(n == 0) //没有苹果
return 1; //有一个方法
if(m > n)
return DFS(n, n);
return DFS(n, m - 1) + DFS(n - m, m);
}
int main(){
int t;
cin >> t;
long long n, m;
while(t--){
cin >> n >> m;
cout << DFS(n, m) << endl;
}
return 0;
}
总时间限制:
1000ms
内存限制:
65536kB
描述
给定两个正整数,求它们的最大公约数。
输入
输入一行,包含两个正整数(<1,000,000,000)。
输出
输出一个正整数,即这两个正整数的最大公约数。
样例输入
6 9
样例输出
3
提示
求最大公约数可以使用辗转相除法:
假设a > b > 0,那么a和b的最大公约数等于b和a%b的最大公约数,然后把b和a%b作为新一轮的输入。
由于这个过程会一直递减,直到a%b等于0的时候,b的值就是所要求的最大公约数。
比如:
9和6的最大公约数等于6和9%6=3的最大公约数。
由于6%3==0,所以最大公约数为3。
这个题就是辗转相除法
#include
using namespace std;
int gcd(int n, int m){
if(m == 0)
return n;
else
return gcd (m, n % m);
}
int main (){
int n, m;
cin >> n >> m;
cout << gcd(n, m);
return 0;
}