题目:http://community.topcoder.com/stat?c=problem_statement&pm=12478&rd=15494
参考:http://apps.topcoder.com/wiki/display/tc/SRM+574
由于最多13个点,而且points中最少2个元素,故只需确定最多11个元素顺序,可用暴力法,最多只有11! 种情形,使用回溯法剪枝,实际要判断的情形最差情况下也比11!少的多。
代码:
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <bitset>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <ctime>
#include <climits>
using namespace std;
#define CHECKTIME() printf("%.2lf\n", (double)clock() / CLOCKS_PER_SEC)
typedef pair<int, int> pii;
typedef long long llong;
typedef pair<llong, llong> pll;
#define mkp make_pair
/*************** Program Begin **********************/
class PolygonTraversal2 {
public:
vector <int> points;
set <int> have;
int n, start;
int cnt;
bool isIntersect(int p)
{
int s = points.size();
int pre = points[s - 1];
int mx = max(p, pre);
int mi = min(p, pre);
for (int i = 0; i < s - 1; i++) {
int p1 = points[i], p2 = points[i + 1];
if ( ( (p1 > mi && p1 < mx) && (p2 < mi || p2 > mx) )
|| ( (p2 > mi && p2 < mx) && (p1 < mi || p1 > mx) )) {
return true;
}
}
return false;
}
void backtrack()
{
// base case
if (points.size() == n) {
if (isIntersect(start)) {
++cnt;
}
}
for (int i = 1; i <= n; i++) {
if (have.find(i) == have.end()) {
// 未加入点
if (isIntersect(i)) {
// 符合条件,加入
points.push_back(i);
have.insert(i);
backtrack();
points.pop_back(); // 恢复
have.erase(i);
}
}
}
}
int count(int N, vector <int> points) {
int res = 0;
this->n = N;
this->points = points;
this->have = set<int>(points.begin(), points.end());
this->start = points[0];
cnt = 0;
backtrack();
res = cnt;
return res;
}
};
/************** Program End ************************/