Problem Description
我們看到過很多直線分割平面的題目,今天的這個題目稍微有些變化,我們要求的是n條折線分割平面的最大數目。比如,一條折線可以將平面分成兩部分,兩條折線最多可以將平面分成7部分,具體如下所示。
Input
輸入數據的第一行是一個整數C,表示測試實例的個數,然後是C 行數據,每行包含一個整數n(0<n<=10000),表示折線的數量。
Output
對於每個測試實例,請輸出平面的最大分割數,每個實例的輸出佔一行。
Sample Input
2
1 2
Sample Output
2
7
分析:
交點決定了射線和線段的條數,進而決定了新增的區域數。當n-1條折線時,區域數爲f(n-1)。爲了使增加的區域最多,則折線的兩邊的線段要和n-1條折線的邊,即2*(n-1)條線段相交。那麼新增的線段數爲4*(n-1),射線數爲2。但要注意的是,折線本身相鄰的兩線段只能增加一個區域。
故:
f(n) = f(n-1) + 4(n-1) + 2 - 1【記憶化+打表即可】
【繼續優化可得到線性答案】
= f(n-1) + 4(n-1) + 1
= f(n-2) + 4(n-2) + 4(n-1) + 2
……
= f(1) + 4 + 4*2 + …… + 4(n-1) + (n-1)
= 2n2 - n + 1
AC代碼:
#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <set>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;
#define INF 0X3F3F3F
ll ans[10005];
ll f(ll x) {
if (ans[x] == 0)
return ans[x] = 2 * f(x - 1) + 1;
else
return ans[x];
}
int main() {
ans[1] = 2;
ans[2] = 7;
for (int i = 2; i <= 10001; i++)
{
ans[i] = ans[i - 1] + 4 * i - 3;
}
int T;
while (cin >> T) {
while (T--) {
ll n;
cin >> n;
cout << ans[n] << endl;
}
}
return 0;
}