• [bzoj1800]fly 飞行棋<暴力>


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1800

    说实话我这几天运气不错,随便在bzoj上找题都可以找到水题,这题在代码上没有丝毫难度,只是如果没想通的话可能做起来会比较吃力,因为暴力也是需要技巧的

    方法:

      这个图形是个圆,要在圆上找矩形。

      然后矩形的特征是啥?四个角90度?好吧这不是重点,重点是矩形的对角线相等

      然后矩形是内接与这个圆的,所以我们又可以想到,圆的内接矩形对角线等于圆的直径

      直径,圆的任何一条直径将圆的面积分成相等的两半,直径所在的端点也将周长分成相等的两半

      只要想通这里,那么思路就来了,如果把弧长相加,能等于周长一半,说明找到一条直径,然后暴力搜索一遍找到所有直径,即所有的对角线。

      然后你可以发现,每两条对角线都可以形成一个合法矩形,那么只要找出对角线数和矩形个数之间的关系就可以了。

    关系:这个关系还是很好推的,想一想多边形顶点个数和对角线个数怎么找的,类比着找。

         设有ans条对角线,每一条对角线都可以和剩下的ans-1条配对形成矩形,但是如果全部配对了会有重复,你随便画个图就可以发现,每个矩形都只是重复一次,

         那么就直接除以2就行,所以公式就是   tot=(ans*ans)/2

    然后这个主要步骤处理方法比较多,反正都是暴力,我举两个处理的小例子吧

    例1:

     1 for(int i=1;i<n;i++)//sum是周长的一半
     2     {
     3         k+=dis[i];//k是累加的长度
     4         while(k>sum)
     5         {
     6             k-=dis[++j];
     7         }
     8         if(k==sum)
     9         {
    10             ans++;
    11         }    
    12     }
    View Code

    例2:

     1     for(int i=1;i<=n;i++)
     2 //pos是与1配对的对角线另一点,找到这一个点是为了避免对角线重复
     3     {
     4         tot=0;//tot和例1的k意义相同
     5         for(int h=i;h<=n;h++)
     6         {
     7             tot+=dis[h];
     8             if(tot>=sum)
     9             {
    10                 if(i==1)pos=h;
    11                 if(tot==sum)ans++;
    12                 break;
    13             }
    14         }
    15         if(i>=pos)break;
    16     }
    View Code

    暴力的方式还有很多,这就简单的介绍两种

    然后我们看一看完整的代码

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #define maxn 25
     5 using namespace std;
     6 
     7 int sum,ans,dis[maxn],k,j;
     8 
     9 int main()
    10 {
    11     int n;
    12     scanf("%d",&n);
    13     for(int i=1;i<=n;i++)
    14     {
    15         scanf("%d",&dis[i]);
    16         sum+=dis[i];
    17     }
    18     sum=sum>>1;
    19 /*    for(int i=1;i<n;i++)
    20     {
    21         k+=dis[i];
    22         while(k>sum)
    23         {
    24             k-=dis[++j];
    25         }
    26         if(k==sum)
    27         {
    28             ans++;
    29         }    
    30     }*/
    31     int tot=0,pos=0;
    32     for(int i=1;i<=n;i++)
    33     {
    34         tot=0;
    35         for(int h=i;h<=n;h++)
    36         {
    37             tot+=dis[h];
    38             if(tot>=sum)
    39             {
    40                 if(i==1)pos=h;
    41                 if(tot==sum)ans++;
    42                 break;
    43             }
    44         }
    45         if(i>=pos)break;
    46     }
    47     
    48     
    49     cout<<ans*(ans-1)/2;
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    MyBatis学习(一)
    ORM框架
    Java 核心技术点之注解
    git 分支 合并
    TensorFlow——零碎语法知识点
    TensorFlow——深入MNIST
    tensorflow——MNIST机器学习入门
    TensorFlow——小练习:feed
    TensorFlow——小练习:counter
    TensorFlow——交互式使用会话:InteractiveSession类
  • 原文地址:https://www.cnblogs.com/Danzel-Aria233/p/7289414.html
Copyright © 2020-2023  润新知