UVA 12651 Triangles

You will be given N points on a circle. You must write a program to determine how many distinct
equilateral triangles can be constructed using the given points as vertices.
The gure below illustrates an example: (a) shows a set of points, determined by the lengths of the
circular arcs that have adjacent points as extremes; and (b) shows the two triangles which can be built
with these points.
Input
The input contains several test cases. The rst line of a test case contains an integer N , the number
of points given. The second line contains N integers Xi , representing the lengths of the circular arcs
between two consecutive points in the circle: for 1  i  (N   1), Xi
represents the length of the arc
between between points i and i + 1; XN represents the length of the arc between points N and 1.
Output
For each test case your program must output a single line, containing a single integer, the number of
distinct equilateral triangles that can be constructed using the given points as vertices.
Restrictions
 3  N  10
5
 1  Xi  10
3


, for 1  i  N
Sample Input
8
4 2 4 2 2 6 2 2
6
3 4 2 1 5 3
Sample Output
2

1

#include <iostream>
#include <stdio.h>
#include <queue>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
#include <map>
#include <stack>
#include <math.h>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std ;
typedef long long LL ;
const int M=200008 ;
int num[M] ,N ,Len ,num2[M];
int L_sum[M] ,R_sum[M] ;
int judge_Left(int id){
   int Left=id;
   int Right=Min(id+N-1,N+N) ;
   int mid ;
   while(Left<=Right){
        mid=(Left+Right)>>1 ;
        if(L_sum[mid]-L_sum[id-1]==Len)
             return 1 ;
        else if(L_sum[mid]-L_sum[id-1]>Len)
             Right=mid-1 ;
        else
             Left=mid+1 ;
   }
   return 0 ;
}
int judge_Right(int id){
   id=N+1-id ;
   id++ ;
   int Left=id;
   int Right=Min(id+N-1,N+N) ;
   int mid ;
   while(Left<=Right){
        mid=(Left+Right)>>1 ;
        if(R_sum[mid]-R_sum[id-1]==Len)
             return 1 ;
        else if(R_sum[mid]-R_sum[id-1]>Len)
             Right=mid-1 ;
        else
             Left=mid+1 ;
   }
   return 0 ;
}
int main(){
   int s  ,ans ;
   while(scanf("%d",&N)!=EOF){
        s=0 ;
        ans=0 ;
        L_sum[0]=0 ;
        for(int i=1;i<=N;i++){
            scanf("%d",&num[i]) ;
            num2[N-i+1]=num[i] ;
            s+=num[i] ;
            L_sum[i]=L_sum[i-1]+num[i] ;
        }
        if(s%3){
            puts("0") ;
            continue ;
        }
        Len=s/3 ;
        for(int i=1;i<=N;i++)
            L_sum[i+N]=L_sum[i+N-1]+num[i] ;
        R_sum[0]=0 ;
        for(int i=1;i<=N;i++)
             R_sum[i]=R_sum[i-1]+num2[i] ;
        for(int i=1;i<=N;i++)
             R_sum[i+N]=R_sum[i+N-1]+num2[i] ;
        for(int i=1;i<=N;i++){
            if(judge_Right(i)&&judge_Left(i))
                ans++ ;
        }
        printf("%d
",ans/3) ;
   }
   return 0 ;
}

原文地址:https://www.cnblogs.com/liyangtianmen/p/3381672.html