問題 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;
}