<QluOJ2018NewCode>计算几何(寄蒜几盒)
题目描述
现在有一个圆圈,圆圈上有若干个点,请判断能否在若干个点中选择三个点两两相连组成一个等边三角形?
这若干个点在圆圈上按顺时针顺序分布。
如果可以的话输出"Yes"(不含引号)
不可以的话输出"No"(不含引号)
这若干个点在圆圈上按顺时针顺序分布。
如果可以的话输出"Yes"(不含引号)
不可以的话输出"No"(不含引号)
输入
第一行一个整数n,表示圆圈上有n个点
第二行n个整数,分别表示第1个点与第2个点之间圆弧的长度、第2个点与第3个点之间圆弧的长度······第n个点与第1个点之间圆弧的长度
3 <= n <= 10^6
1 <= x_i <= 1000 ( 1 <= i <= n)
第二行n个整数,分别表示第1个点与第2个点之间圆弧的长度、第2个点与第3个点之间圆弧的长度······第n个点与第1个点之间圆弧的长度
3 <= n <= 10^6
1 <= x_i <= 1000 ( 1 <= i <= n)
输出
如果可以组成等边三角形则输出"Yes"(不含引号)
否则输出"No"(不含引号)
否则输出"No"(不含引号)
样例输入
样例输入1:
4
1 1 2 2
样例输入2:
8
4 2 4 2 2 6 2 2
样例输出
样例输入1:
Yes
样例输入2:
Yes
提示
对于样例2配图:
思路:
可以把圆看成一条线,解法算是二分+前缀和。
如果里面有等边三角形,也就是说圆弧能等分成三份,于是第一个判断条件就是:
1)周长%3==0
那么,三角形的边长就是周长/3,所以三个点假设为a,b,c,三个点到1号点的距离就分别是:xa,xa+t,xa+t+t,其中t=周长/3。
2)查找xa,xa+t,xa+2t是否存在(二分)
#include<cstdio> #include<iostream> #include<cmath> using namespace std; int a[1000005]; int x[1000010]; int n; bool find(int mis,int left,int right){ while(left+1<right){ int mid=(left+right)/2; if(x[mid]==mis){ return true; }else{ if(x[mid]<mis){ left=mid; }else{ right=mid; } } } return false; } bool check(int t){ for(int i=0;i<=n-2;i++){//因为最少三个点嘛 int p1=x[i]+t; int p2=x[i]+2*t; if(find(p1,0,n)==true&&find(p2,0,n)==true){ return true; } } return false; } int main(){ cin>>n; x[0]=0; for(int i=1;i<=n;i++){ cin>>a[i]; x[i]=x[i-1]+a[i]; } if(x[n]%3!=0){ cout<<"No"; }else{ if(check(x[n]/3)==true){ cout<<"Yes"; }else{ cout<<"No"; } } return 0; }