zoukankan      html  css  js  c++  java
  • bzoj1800[Ahoi2009]fly 飞行棋 暴力枚举

    找了道bzoj的水题,千年难得一遇。

    建议初学者做做,然而我个蒟蒻初学时应该A不了.....

    < http://www.lydsy.com/JudgeOnline/problem.php?id=1800 > 地址啦啦啦就来了。

    进入正题,先看题目

    Description

    给出圆周上的若干个点,已知点与点之间的弧长,其值均为正整数,并依圆周顺序排列。 请找出这些点中有没有可以围成矩形的,并希望在最短时间内找出所有不重复矩形。

    Input

    第一行为正整数N,表示点的个数,接下来N行分别为这N个点所分割的各个圆弧长度

    Output

    所构成不重复矩形的个数

    Sample Input

    8
    1
    2
    2
    3
    1
    1
    3
    3

    Sample Output

    3

    HINT

    N<= 20


     其他什么都不看,就看到 N<=20 不管说什么都是暴力吧。

    在看看题目,大意:  N个点在一个圆上按输入顺序依次排列,已知相邻两点距离a[i,i+1],求这些点能组成的不重复矩形个数。(大意比题目还长,主要是我语文不好)

    看完这些,还要看的就是上面这个神奇的图了,看完这个就肯定是水题一道。

    可以发现:是矩形的条件就是对边相等,实际上可以抽象成对边两个点在圆上的距离a[i,i+1],那么判是矩形的条件就出来了

    这道题的话,效率4重到2重都可以打,我比较蒟,就打了个4重。

    思路就差不多是这样的:(建议一边看图一边看题解)

      4重枚举矩形的4个顶点,i枚举左上角的,j枚举右上角的,k枚举右下角的,k1枚举左下角的。

      这时就会发现需要预处理圆上按输入顺序的所有点的距离,a[i,j]表示 i 到 j 的距离。

      a[i,j]=a[i,i+1]+a[i+1,i+2]+...+a[j-1,j]; 这个为什么我应该不用说吧。

      是矩形的条件:1、a[i,j]=a[k,k1](第一组对边相等);

                        2、a[j,k1]=?  然后就发现 i 到 k1 的边不会是那个想要的边,可以用sum先计算一下圆的周长,这条边就可以这样表示  sum-a[i,k1];

                            and then(措不及防的飙英语)    a[j,k1]=sum-a[i,k1];(第二组对边相等);

       然后就没有然后了, and then has no and then(措不及防的又飙了英语,还飙得这么不标准)

       当然还有代码:  

    pascal:

    var a:array[0..50,0..50]of longint;
        n,i,j,x,k,k1:longint;
        ans,sum:int64;
    begin
      read(n);
      for i:=1 to n do
      begin
        read(x);
        a[i,i+1]:=x; //这里是把读入数据先弄成a[i,i+1]的形式
        sum:=sum+x;//sum就是圆周长
      end;
      for i:=1 to n do
      begin
        for j:=i+2 to n do// j 从 i+2 的原因是 i+1是知道的
        a[i,j]:=a[i,j-1]+a[j-1,j];//预处理a[i,j],因为是按读入顺序,所以如果j<i的数据也用不到,当然也可以先预处理,看心情
      end;
      for i:=1 to n do//枚左上角
      for j:=i+1 to n do//枚右上角
      for k:=j+1 to n do//枚右下角
      for k1:=k+1 to n do//枚左下角
      if (a[i,j]=a[k,k1])and(a[j,k]=sum-a[i,k1]) then  //判两组对边相等
      begin
        inc(ans);  //答案加一
      end;
      writeln(ans);
    end.
    

      

    c++:

        你说什么,我也不知道为什么没有c++的代码(懒得打,有时间补上)。


     

    #include<iostream>
    using namespace std;
    int main()
    {
      int a[100][100]={0};
      int n,x,i;
      int sum;
      cin>>n;
      sum=0;
      
      for (i=1;i<=n;i++){
      	cin>>x;
      	a[i][i+1]=x;
      	sum=sum+x;
      }
      
      int j;
      for (i=1;i<=n;i++)
      	for (j=i+2;j<=n;j++){
      		a[i][j]=a[i][j-1]+a[j-1][j];
    	  }
    	  
      int k,k1,ans;
      ans=0;
      for (i=1;i<=n;i++)
        for (j=i+1;j<=n;j++)
          for (k=j+1;k<=n;k++)
            for (k1=k+1;k1<=n;k1++)   
            if (a[i][j]==a[k][k1] && a[j][k]==sum-a[i][k1]) ans=ans+1;
            
      cout<<ans;
    }
    

      

    可能有打错的地方,可以指正哦!

    c++最近才自学,可能翻译代码对我来说有点难,所以没代码不能怪我。

  • 相关阅读:
    golang切片使用append追加内容导致切片值异常问题
    golang对通道进行select,case生效异常问题
    golang defer未按预期顺序执行
    GO实现无锁队列
    mysql建表报错:Specified key was too long
    右键快捷键
    算法与数据结构基础<三>----数据结构基础之栈和队列加强之用栈实现队列
    ios从入门到放弃之C基础巩固-----数组、字符串
    获取股票数据【使用JQData查询行情数据、财务指标、估值指标】
    IDEA配置.gitignore不生效的问题
  • 原文地址:https://www.cnblogs.com/Bunnycxk/p/6218249.html
Copyright © 2011-2022 走看看