zoukankan      html  css  js  c++  java
  • 2018.11.26 QLU新生赛部分题解

    问题 L: 寄蒜几盒?
    
    题目描述
    
    现在有一个圆圈,圆圈上有若干个点,请判断能否在若干个点中选择三个点两两相连组成一个等边三角形? 
    这若干个点在圆圈上按顺时针顺序分布。 
    如果可以的话输出"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
    题目描述(L: 寄蒜几盒?)

    传送门

    题解:

      预备知识补充:

        (1):在同圆或等圆中,相同的圆心角对应的弦相等,对应的弧也相等。L: 寄蒜几盒?

      会了这个知识,那这道题差不多就做出来了。

      相关变量解释:

      sum[maxn]:..................................sum[ i ]表示第1个点距第i+1个点的距离 ,也就是前缀和。

      步骤:

      (1):特判圆周长sum[ n ]是否整除3,如果不整除,直接输出"No"。

      (2):如果sum[ n ]整除3,遍历一遍数组,判断是否含有三点a,b,c,使得ab,bc,ca间的距离等于sum[ n ]/3,如果有,输出"Yes",否则输出"No"。

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 const int maxn=1e6+10;
     5 
     6 int n;
     7 int a[maxn];
     8 int sum[maxn];
     9 
    10 bool isSat(int p1,int p2){//判断p1,p2点是否在范围内
    11     return p1 <= sum[n] && p2 <= sum[n];
    12 }
    13 bool Check(int p1)//二分查找
    14 {
    15     int l=0,r=n+1;
    16     while(r-l > 1)
    17     {
    18         int mid=l+((r-l)>>1);
    19         if(sum[mid] == p1)
    20             return true;
    21         if(sum[mid] < p1)
    22             l=mid;
    23         else
    24             r=mid;
    25     }
    26     return false;
    27 }
    28 char *Solve()
    29 {
    30     if(sum[n]%3 != 0)//特判
    31         return "No";
    32     int d=sum[n]/3;
    33     for(int i=1;i <= n;++i)//遍历所有点,判断是否含有满足条件的三个点
    34     {
    35         int p1=sum[i]+d,p2=sum[i]+2*d;
    36         if(isSat(p1,p2) && Check(p1) && Check(p2))//二分查找点p2,p2是否存在
    37             return "Yes";//如果存在,返回"Yes"
    38     }
    39     return "No";
    40 }
    41 int main()
    42 {
    43     scanf("%d",&n);
    44     sum[0]=0;
    45     for(int i=1;i <= n;++i)
    46         scanf("%d",a+i),sum[i]=sum[i-1]+a[i];//前缀和
    47 
    48     printf("%s
    ",Solve());
    49 }
    View Code

      对算法时间复杂度的分析:

        每遍历一个点都需要log(n)的复杂度查找是否含有p1,p2点,一共遍历了n个点,所以总的时间复杂度为O( nlog(n) ),106完全可以过。

  • 相关阅读:
    Golang哲学思想
    Outlook与Hotmail的设置
    Android 经验: 5555 端口会被 adb 误认为 emulator
    QT程序探测所需DLL,静态连接和打包
    VS编译的QT程序发布时产生的AppCrash问题
    新语言和旧语言
    MMU和TLB
    FMX的综合评价
    Windows核心编程学习九:利用内核对象进行线程同步
    QListWidget特别简单,但有两种添加item的方式
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/10020199.html
Copyright © 2011-2022 走看看