递归练习

问题 A: 吃糖果
递归简单题。

#include <iostream>
using namespace std;
int f(int n)
{
	if (n == 1 || n == 0)
	{
		return 1;
	}
	return f(n - 1) + f(n - 2);
}
int main()
{
	int n;
	while (cin >> n)
	{
		cout << f(n) << endl;
	}
	return 0;
}

问题 B: 数列
这个比较简单,一遍就过了,嘻嘻。

#include <iostream>
using namespace std;
int a[25];
int f(int n)
{
	if (n == 1 || n == 2)
	{
		return 1;
	}
	return f(n - 1) + f (n - 2);
}
int main()
{
	int m;
	cin >> m;
	while (m--)
	{
		int n;
		cin >> n;
		for (int i = 1; i <= n * 2 - 2; i++)
		{
			a[i] = f(i);
		}
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= 2 * (n - i); j++)
			{
				cout << " ";
			}
			for (int j = 0; j <= 2 * i - 2; j++)
			{
				cout << a[j] << " ";
			}
			cout << endl;
		}
	}
	return 0;
}

问题 C: 神奇的口袋
这题气死我了,bug改了两个小时,真是无语。错误原因在于每次都要ans = 0,但是我写。。。还有要注意两个if条件句不能颠倒,为什么呢?因为n是物品的个数,每次选了一个都会减一,所以在递归的开始要先判断体积是否达到w,然后才是判断是否继续递归选物品。这样可能不好理解,我们举个特殊例子来说明。比如输入2 12 28,当n = 0时,w = 0,此时如果两个if条件句反了,就会出现错误的输出0。

#include <iostream>
#include <cstring> 
using namespace std;
int a[25];
int ans;
void f(int n, int w)
{
	if (w == 0)
	{
		ans++;
		return;
	}
	if (n == 0 || w < 0)
	{
		return;
	}
	f(n - 1, w - a[n]);
	f(n - 1, w);
}
int main()
{
	int n;
	while (cin >> n)
	{
		ans = 0;
		for (int i = 1; i <= n; i++)
		{
			cin >> a[i];
		}
		f(n, 40);
		cout << ans << endl;
	}
	return 0;
}

问题 D: 八皇后
这个八皇后问题在今年寒假在蓝书上看到过,那时候还不是特别懂,现在感觉容易理解了,不过这题和求解方法种数还不太一样,这个题要记录每个皇后的坐标,然后排好序,最后输出就行了。这题的难点是两斜线如何标记,其实以前也有发现过这种同一斜线上的点x,y坐标的规律,但是不知道如何利用规律来标记。其实只要用两个数组,下标分别存储x+y、x-y的值,但是由于x-y可能小于0,所以代码中加上了一个8。

#include <iostream>
#include <algorithm>
using namespace std;
int c[10], x1[20], x2[20];
int check(int r, int i)
{
    return !c[i] && !x1[r + i] && !x2[r - i + 8];
}
int ans, t[10], a[100];
void dfs(int r)
{
	if (r > 8)
	{
		int k = 0;
		for (int i = 1; i <= 8; i++)
		{
			k = k * 10 + t[i];
		}
		ans++;
		a[ans] = k;
		return;
	}
	for (int i = 1; i <= 8; i++)
	{
		if (check(r, i))
		{
			c[i] = x1[r + i] = x2[r - i + 8] = 1;
			t[r] = i;
			dfs(r + 1);
			t[r] = 0;
			c[i] = x1[r + i] = x2[r - i + 8] = 0;
		}
	}
}
int main()
{
	int n;
	cin >> n;
	dfs(1);
	sort(a, a + ans);
	while (n--)
	{
		int x;
		cin >> x;
		cout << a[x] << endl;
	}
	return 0; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值