Maratona de Programa¸c˜ao da SBC – ACM ICPC – 2013 F Triangles

题意是一个圆上,给出n个点之间的距离,最后的距离是最后一个点跟第一个点之间的距离,问能组成多少个等边三角形。


容易想到圆的周长不能整除3的话一定无法构成等边三角形,所以先特判这种情况。然后可以发现,每条线段必定是n个连续的点,这样可以找到2*n个点,判断从当前点开始,能否在n个点之内,正好找到3段长度有多少种,时间复杂度是O(n*n),需要优化,建立前缀和数组,二分查找当前前缀和+sum/3的数的坐标,大于i+n就跳出循环,最后得到的数要整除3,如 3 4 2 1 5 3,计算的是 4 2 1 5 3 3,1 5 3 3 4 2,3 3 4 2 1 5。有重复计算。

代码实现:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e6+5;
int a[maxn];
ll pre[maxn*2];

int main()
{
	int n,i,j,k;
	scanf("%d",&n);
	ll sum=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]),sum+=a[i];
		a[i+n]=a[i];
	}
	pre[0]=a[0];
	for(i=1;i<2*n;i++)
	pre[i]+=pre[i-1]+a[i];
	if(sum%3)
	{
		printf("0\n");
		return 0;
	}
	ll t=sum/3,s=0,temp;
	for(i=0;i<n;i++)
	{
		ll c;
		if(i)
		c=pre[i-1]+t,temp=i-1;
		else
		c=t,temp=i;
		bool flag=0;
		int x=lower_bound(pre,pre+2*n,c)-pre;//cout<<x<<' ';
		if(x>=i+n)
		flag=1;
		if(flag)
		continue;
		c=pre[x]+t;temp=x;
		x=lower_bound(pre,pre+2*n,c)-pre;//cout<<x<<' ';
		if(x>=i+n)
		flag=1;
		if(flag)
		continue;
		c=pre[x]+t;temp=x;
		x=lower_bound(pre,pre+2*n,c)-pre;//cout<<x<<"****"<<endl;
		if(x>=i+n)
		flag=1;
		if(flag)
		continue;
		if(!flag)
		s++;
	}
	printf("%lld\n",s/3);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值