欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2020牛客寒假算法基础集训营1 A

程序员文章站 2022-06-07 13:05:47
...

题目

2020牛客寒假算法基础集训营1 A
2020牛客寒假算法基础集训营1 A
2020牛客寒假算法基础集训营1 A

思路

找底、高一个为1一个为2的三角形
已知共有n行m列

第一类:

2020牛客寒假算法基础集训营1 A
2020牛客寒假算法基础集训营1 A
每一行上,以=长为2的边为底(黑色边)向外找三角形

  • 每3个点构成一个长为2的底,那么一行有m个点(m列),就有(m-2)个底。

    相邻行的点均可做这个底对应的那个顶点,那么一个底就有m个三角形(相邻行有m个点)

    那么这一行就有(m-2) * m 个三角形,两行就有 (m-2) * m * 2个

  • 以两行为一个大单位,那么在nm的格点中就有(n-1)个这样的大单位。
    2020牛客寒假算法基础集训营1 A
    那么n
    m的格点中就有 (m-2) * m * 2 * (n-1) 个三角形

第二类:

与第一类类似,
但是,是在每一列上,以=长为2的边为底(黑色边)向外找三角形
2020牛客寒假算法基础集训营1 A
分析与第一类类似,只是行列的关系对调。
公式是 (n-2) * n * 2 * (m-1)

第三类:

是在每一行上,找以=长为1的边为底(黑色边),并且高与坐标轴不垂直的三角形

如果高与坐标轴垂直,就与前两种情况找的重复了!!!如下:
2020牛客寒假算法基础集训营1 A
下图为不垂直的:2020牛客寒假算法基础集训营1 A
2020牛客寒假算法基础集训营1 A

  • 每2个点构成一个长为1的底,那么一行有m个点(m列),就有(m-1)个底。

隔行的点刨除去2个形成垂直的高的点,剩下(m-2)个可以当顶点的点,那么一个底就有(m-2)个三角形

那么这一行就有(m-1) * (m-2) 个三角形,三行就有 (m-1) * (m-2) * 2个(中间那一行不能形成这样的三角形)

  • 以三行为一个大单位,那么在nm的格点中就有(n-2)个这样的大单位。
    那么n
    m的格点中就有 (m-1) * (m-2) * 2 * (n-2) 个三角形
    即(m-1) * (m-2) * (2n-4)

第四类:

与第三类类似,但是
是在每一列上,找以=长为1的边为底(黑色边),并且高与坐标轴不垂直的三角形

 分析与第三类类似,只是行列的关系对调。
 公式为(n-1) *  (n-2) *  (2m-4)

特殊情况:

    if(n==2&&m==2){cout<<'0'<<endl;return 0;}//2点*2点

AC代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
inline ll mm(ll a, ll b, ll m)
{
    ll c = a*b-(ll)((long double)a*b/m+0.5)*m;
    return c<0 ? c+m : c;  //就是算的a*b%m;
}
int main()
{
    int n,m;
    cin>>n>>m;
    if(n==2&&m==2){cout<<'0'<<endl;return 0;}
    else
    {
        cout<<(mm(mm(m-2,m*2,1000000007),n-1,1000000007)+mm(mm(n-2,n*2,1000000007),m-1,1000000007)+mm(mm(m-1,m-2,1000000007),n*2-4,1000000007)+mm(mm(n-1,n-2,1000000007),m*2-4,1000000007))%1000000007<<endl;
    }
    return 0;
}

相关标签: 牛客