zoukankan      html  css  js  c++  java
  • 2020牛客寒假算法训练营第一场题解(持续更新中)

    A题honoka和格点三角形

    这一题要求计算格点图中”好三角形“的数量。好三角形是面积为1,至少有一条边平行于x轴或y轴,并且顶点都在格点上的三角形。

    那么我们可以分两种情况考虑,分别为同时平行于x轴和y轴以及只有一条边平行。

    第一种情况很简单,在每个1*3的矩形中都有4个,那么在n*m的矩形中一共有(m-2)*(n-1)+(n-2)*(m-1)种这样的不同矩形,所以就有((m-2)*(n-1)+(n-2)*(m-1))*4个矩形。

    第二种情况又可以分为两种情况,分别为底为2高为1和底为1高为2两种情况。

    以底为2高为1为例,设x轴为m,y轴为n,这里需要注意的就是不要与第一种情况重复。

    如果底与x轴平行,我们可以得到(m-2)*n个不同的底,对于每个底来说,只需要选择第三个点即可,因为第三个点选择的时候不能构成直角三角形,否则会重复,所以对于每一个底,只能选择(m-2)个点作为其顶点,然后对于每一行来说,都可以往上取或者往下取,但是由于最下面一行只能往上取和最上面一行只能往下取,所以我们把这两行合并,最后就得到这样的三角形有((m-2)*(m-2)*(n-1))*2个,那么以y轴为底就有((n-2)*(n-2)*(m-1))*2个。

    同理可得,以底为1的三角形分别有((m-1)*(m-2)*(n-2))*2和((n-1)*(n-2)*(m-2))*2个。最后只要把这5种全部加起来就行了。

    在这里我犯了一个非常低级的错误,那就是取模。写这个题解也就是要提醒自己以后不要犯一样的错误。下面是错误示范

      ll ans=0;
      ans+=((m-2)*(n-1)+(n-2)*(m-1))*4%mod;
      ans+=((m-2)*(m-2)*(n-1))*2%mod;
      ans+=((n-2)*(n-2)*(m-1))*2%mod;
      ans+=((m-1)*(m-2)*(n-2))*2%mod;
      ans+=((n-1)*(n-2)*(m-2))*2%mod;
      cout<<ans%mod<<endl;
    View Code

     一定要记得,取模一定要对每一个元素都要取模!!!!以下为AC代码

    #include <iostream>
    using namespace std;
    
    #define ll long long
    ll mod=1000000007;
    
    int main()
    {
      ll n,m;
      cin>>n>>m;
      ll ans=0;
      ans+=(((m-2)%mod*(n-1))%mod+((n-2)*(m-1)%mod))*4%mod;
      ans+=((m-2)%mod*(m-2)%mod*(n-1)%mod)*2%mod;
      ans+=((n-2)%mod*(n-2)%mod*(m-1)%mod)*2%mod;
      ans+=((m-1)%mod*(m-2)%mod*(n-2)%mod)*2%mod;
      ans+=((n-1)%mod*(n-2)%mod*(m-2)%mod)*2%mod;
      ans%=mod;
      cout<<ans<<endl;
      return 0;
    }
    View Code

     B题kotori和bangdream

    一个算数学期望的水题,知道数学期望就能做,就直接上代码了

    #include<iostream>
    int main()
    {
        double n,x,a,b;
        scanf("%lf%lf%lf%lf",&n,&x,&a,&b);
        printf("%.2f",n*((x/100.00)*a+(1-x/100.00)*b));
    }
    View Code

     J题μ's的影响力

    这个题是一个不是很明显的矩阵快速幂,关于矩阵快速幂的问题我在别的博客已经讲过,这里就不讲,我们可以看到给的递推式为

    由于ab是一个常数,我们把这个常数设为t,那么我们首先写一下前几项,可以很轻易的得到

    f(1)=x   f(2)=y   f(3)=xyt   f(4)=xy2t2   f(5)=x2y3t4    f(6)=x3y5t7    f(7)=x5y8t12

    然后我们分别看x,y以及t的系数,我们看到他们的系数随着n的变换形成的是斐波那契额数列,如果我们把斐波那契额的第n项设为feb(n)的话

    那么我们可以得到f(n)的表达式为

    f(n)=xfeb(n-2)yfeb(n-1)t(feb(n-2)+feb(n-1)-1)

    由于x,y,t均为常数,所以要想求f(n),我们只需要求出斐波那契的数列的第n-1项和第n-2项即可。

    求斐波那契的第n项是个非常经典的矩阵快速幂,我们只要设矩阵为

    1 1                               2 1                  3 2                    5 3

    1 0   那么对其2次方为 1 1  三次方为  2 1   四次方为  3 2

    根据矩阵快速幂我们可以很快的得到,但是这里还有一点就是要利用费马小定理

  • 相关阅读:
    C++函数参数传参的本质解析
    C#值类型和引用类型详解
    C#学习笔记(转换)
    C#学习笔记(泛型)
    # Java反射2——获取实体所有属性和方法,并对属性赋值
    Java反射1——扫描某个包下的所有类
    JSR教程2——Spring MVC数据校验与国际化
    JSR教程1——JSR 303
    Github如何撤销提交并清除痕迹
    论文第5章:Android绘图平台的实现
  • 原文地址:https://www.cnblogs.com/zlhdbk/p/12264139.html
Copyright © 2011-2022 走看看