UVA 11139 Counting Quadrilaterals
阿新 • • 發佈:2019-01-27
噢~~智商如此捉雞!
剛開始連樣例都跑不出來(我居然就去交了一遍 (╯‵□′)╯︵┻━┻)
都已經放棄去看題解了。。(搜不到T^T,天亡我也)
只能繼續想,發現對於凹四邊形,相同的點可以構成3個不同的四邊形(臥槽,意外之喜啊~)
然並卵。。。只能想出一個超高複雜度的演算法。。。。求大牛隨手拯救一把 Orz
我是先按照點不同,求出不同的四變形個數A,然後求出凹四邊形的個數B
ans = A + 2 * B
至於求凹四邊形的個數,簡直不能再爛了。。。
#include #include #include using namespace std; typedef long long ll; #define rep(i,n) for(int i=0;i= 0 ? x : -x; } ll init_cal(int i,int j,int x,int y) { int S = (x * j - y * i) / 2; if(S < 0) S = -S; int B = g[x][y] + g[i][j] + g[Abs(x-i)][Abs(y-j)]; return S + 1 - B / 2; } void init() { mst(g,0); for(int i=0; i<=120; i++) { for(int j=0; j<=120; j++) { g[i][j] = gcd(i,j); } } mst(cnt,0); // 一點為(0,0),遍歷另外兩點,確定一個三角形 for(int i=0; i<=121; i++) { for(int j=1; j<=121; j++) { for(int x=1; x<=121; x++) { for(int y=0; y<=121; y++) { if(x * j - y * i <= 0) break; int a = max(i,x); int b = max(j,y); ll tmp = init_cal(i,j,x,y); // 求整點三角形內部的點 int k; if(i == 0) { if(y != j) k = 2; else k = 1; } else if(y == 0) { if(i != x) k = 2; else k = 1; } else if(i == a && j == b) { k = 2; } else if(x == a && y == b) { k = 2; } else k = 4; // k = 4 表示其上下左右翻轉產生的4種情況,只有當前這種能遍歷到 // k = 2 表示有兩種能遍歷到 // k = 1 表示其餘的都能遍歷到 cnt[a][b] += tmp * k; // 所以cnt[a][b] 記錄的是正好能用長為a,寬為b的矩形包含的凹多邊形的個數 } } } } } int main() { init(); while(~scanf("%d",&n),n) { n++; ll ans = C4(n * n) - C3(n) * n * 2 * (n * n - 3) + C4(n) * 3 * n * 2; for(int i=1; i