问题 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;
}