1. 程式人生 > >UVA 11139 Counting Quadrilaterals

UVA 11139 Counting Quadrilaterals

噢~~智商如此捉雞!

剛開始連樣例都跑不出來(我居然就去交了一遍 (╯‵□′)╯︵┻━┻)

都已經放棄去看題解了。。(搜不到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