幾何題看著就很有畏懼感。這裡用的是最*****的演算法,時間複雜度應該在n^2。還沒看別人的解題報告,不過我猜nlogn的解法是有的。
比如判斷乙個fence是不是valid的時候,這裡將所有的線段兩兩比較,看是否相交。但是有個叫line sweep的演算法,可以在nlogn的時間複雜度內完成。既然accept了,就懶得實現了。。。
判斷兩條線段(line segment)是否相交,stackoverflow上面有很詳細的討論,各種思路都有:
我採用的是這裡的解法:
前者看ac和cd以及bc和cd的向量叉乘符號是否一致。
上面鏈結上有詳述,包括line sweep演算法。
(x1 - x2) * y - (y1 - y2) * x = x1 * y2 - x2 * y1
然後具體判斷的時候,我用的是將整條線分成1000份,看觀察者到這個等分點的連線是否與別的線相交了。
如果有乙個點能看到,則這個線段能看到。
usaco標準解法裡面取了中點,並且將第一條相交的線段標記為可見。這個想法很好,可以減少重複判斷。
也可以先取中點,再二分,效率應該能更高。
我這種最簡單。在這種小資料n=200的情況下也可以過所有測試點。
/* id: thestor1
lang: c++
task: fence4
*/#include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
const int maxn = 200;
int x[maxn], y[maxn];
int n;
// check if ac and cd is counter-clockwise
bool isccw(double x1, double y1, double x2, double y2, double x3, double y3)
bool isintersect(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
else if(isccw(x3, y3, x1, y1, x2, y2) == isccw(x4, y4, x1, y1, x2, y2))
return true;
}bool isvalid()
} }return true;
}bool iscoline(int lineno, int x, int y)
bool isseen(int lineno, int x, int y)
int x2 = x[j];
int y2 = y[j];
int x3 = x[(j + 1) % n];
int y3 = y[(j + 1) % n];
if(isintersect(x, y, px, py, x2, y2, x3, y3))
}if(!blocked)
}return false;
}int main()
} if(v.size() >= 2 && v[v.size() - 2] == n - 2)
fprintf(fout, "%d\n", v.size());
// cout<
USACO Hamming Codes 解題報告
資料小,暴力搜尋可以搞定。但是推薦使用dfs,每個節點 數 有取與不取兩個分支。注意 0是必須出現的。證明如下 最終得到的結果序列中,0是必須出現的,證明如下 如果存在另乙個滿足要求的結果序列s 其最小值為a1 n 0,那麼序列s s n 是滿足條件的最小解,且首元素為0 id xpli1 prog...
Wiggle Subsequence解題報告
這道題和最長子序列,divisible subset題目類似,都可以用o n2 的時間複雜度完成。可以想象,對於第i個數,dp i dp j 1,當且僅當dp j 1 dp i 而且nums j 和nums i 的差值和j所處位置的差值符號相反。所以,如下 class solution if dp ...
The XOR Largest Pair 解題報告
描述 在給定的n個整數a1,a2 an中選出兩個進行xor運算,得到的結果最大是多少?輸入格式 第一行乙個整數n,第二行n個整數a1 an。輸出格式 乙個整數表示答案。樣例輸入 31 2 3 樣例輸出 資料範圍與約定 對於100 的資料 n 10 5,0 ai 2 31。解題思路 由於只要求在n個數...