1. 程式人生 > ><QluOJ2018NewCode>計算幾何(寄蒜幾盒)

<QluOJ2018NewCode>計算幾何(寄蒜幾盒)

計算 假設 style clas 解法 輸入 是否 left con

題目描述

現在有一個圓圈,圓圈上有若幹個點,請判斷能否在若幹個點中選擇三個點兩兩相連組成一個等邊三角形?
這若幹個點在圓圈上按順時針順序分布。
如果可以的話輸出"Yes"(不含引號)
不可以的話輸出"No"(不含引號)

輸入

第一行一個整數n,表示圓圈上有n個點
第二行n個整數,分別表示第1個點與第2個點之間圓弧的長度、第2個點與第3個點之間圓弧的長度······第n個點與第1個點之間圓弧的長度
3 <= n <= 10^6
1 <= x_i <= 1000 ( 1 <= i <= n)

輸出

如果可以組成等邊三角形則輸出"Yes"(不含引號)
否則輸出"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; }

<QluOJ2018NewCode>計算幾何(寄蒜幾盒)