codeforces1146H Satanic Panic

題面

題意

平面上有n個點,兩兩之間連線後,求一共能構成多少個五角星.

做法

首先可以將五角星看作是有5個點的凸包,也就是5個極角排序後遞增的向量首尾相接後得到的圖形.
因此可以記dp[x][y][i]dp[x][y][i]表示從點x到點y經過i個線段的方案數,對所有向量(一個線段可以看作是兩個向量)進行極角排序後,依次來更新dp值,這樣i=1ndp[i][i][5]\sum_{i=1}^ndp[i][i][5]就是答案.

代碼

#include<bits/stdc++.h>
#define ll long long
#define db double
#define N 310
using namespace std;

ll n,xx,ans,dp[N][N][6];
db x[N],y[N];
struct Xd
{
	ll u,v;
	db jd;
	bool operator < (const Xd &u) const{return jd<u.jd;}
}xd[N*N];

int main()
{
	ll i,j,k;
	cin>>n;
	for(i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]);
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
			if(i==j) continue;
			xd[++xx]=(Xd){i,j,atan2(y[j]-y[i],x[j]-x[i])};
		}
	}
	sort(xd+1,xd+xx+1);
	for(i=1;i<=xx;i++)
	{
		dp[xd[i].u][xd[i].v][1]=1;
		for(j=1;j<=n;j++)
		{
			for(k=2;k<=5;k++)
			{
				dp[j][xd[i].v][k]+=dp[j][xd[i].u][k-1];
			}
		}
	}
	for(i=1;i<=n;i++) ans+=dp[i][i][5];
	cout<<ans;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章