2020牛客寒假算法基礎集訓營1—A.honoka和格點三角形【計數】

2020牛客寒假算法基礎集訓營1—A.honoka和格點三角形【計數】鏈接

題目描述
honoka最近在研究三角形計數問題。
她認爲,滿足以下三個條件的三角形是“好三角形”。
1.三角形的三個頂點均爲格點,即橫座標和縱座標均爲整數。
2.三角形的面積爲 。
3.三角形至少有一條邊和 軸或 軸平行。
honoka想知道,在平面中選取一個大小爲 的矩形格點陣,可以找到多少個不同的“好三角形”?由於答案可能過大,請對 取模。
輸入描述:
兩個正整數和( 2\ ≤n,m≤10^9)(2 ≤n,m≤10
9

輸出描述:
面積爲1的格點三角形的數量,對 10^9+7 取模的結果。

示例1
輸入

2 3

輸出

6

說明
格點如下:

。 。 。
。 。 。
不妨設左下角座標爲(1,1),右上角座標爲到(3,2)。
那麼三點座標可選:
(1,1)(1,2)(3,1)
(1,1)(1,2)(3,2)
(1,1)(2,2)(3,1)
(1,1)(3,1)(3,2)
(1,2)(2,1)(3,2)
(1,2)(3,1)(3,2)
所以共有6個。

示例2
輸入

100 100

輸出

7683984

說明
這裏太小寫不下啦。
備註:

可以把面積爲 11 的“好三角形”分爲兩類分開統計:兩條邊和兩個座標軸平行;只有一條邊和某個座標軸平行。
(1)對於第一種情況,一定是 12 或者 21 的形式,一個 12 的矩形中含有4個不同的三角形,同理一個21的矩形中也含有4個不同的三角形
總數是 4*((n-2)(m-1)+(m-2)(n-1))

(2)對於第二種情況,可以分別統計底邊爲 2 、高爲 1 和底邊爲 1 、高爲 2 的情況。要注意底邊靠近邊界時的特殊討論。
①對於底邊爲2,高爲1的情況:

若底邊和x軸平行,那麼底邊橫向移動(指x軸水平移動,下同)有 n-2種可能,“對點”(指底邊相對的點)的某一面選擇有 n-2 種可能(某一面選擇,指的是底邊固定的情況,對點在一條直線上移動所做出的選擇),而底邊縱向移動有 m 種情況,其中有 (m-2)種情況對點可以選擇兩個面,2種情況對點只能選擇一個面(當底邊移動到格點陣邊界的時候)。因此縱向移動摺合爲 2*(m-2)+2,即2*(m-1)
以上可計算爲2*(m-1)(n-2)(n-2)

若底邊和y軸平行,同理可推出 2*(n-1)(m-2)(m-2)
總數是2*(m-1)(n-2)(n-2)+2*(n-1)(m-2)(m-2)

②對於底邊爲1,高爲2的情況,與①類似,若底邊和x軸平行,那麼底邊橫向移動(指x軸水平移動,確保了底爲1)有 n-1種可能,對點”(指不在底邊的另外一點,它確保了高爲2)的某一面選擇有 n-2 種可能(某一面選擇,指的是底邊固定的情況,對點在一條直線上移動所做出的選擇),而底邊縱向移動並且保證高爲2,則有 (m-2)種情況對點可以選擇,以上可計算爲2*(n-1)(n-2)(m-2)

若底邊和y軸平行,同理可推出 2*(m-1)(m-2)(n-2)
總數是2*(n-1)(n-2)(m-2)+ 2*(m-1)(m-2)(n-2)

綜上所述“好三角形”計數爲4*((n-2)(m-1)+(m-2)(n-1))+2*(m-1)(n-2)(n-2)+2*(n-1)(m-2)(m-2)+2*(n-1)(n-2)(m-2)+ 2*(m-1)(m-2)(n-2)

 #include<bits/stdc++.h> 
#include<iostream>
using namespace std;
const int mod=1e9+7;
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);    //2-4牛客 A題 
	long long n,m;
	cin>>n>>m;
	long long a,b,c;
	a=4*((n-2)%mod*(m-1)%mod+(n-1)%mod*(m-2)%mod)%mod;
	b=2*((n-2)%mod*(n-2)%mod*(m-1)%mod+(n-1)%mod*(m-2)%mod*(m-2)%mod)%mod;
	c=2*((n-1)%mod*(n-2)%mod*(m-2)%mod+(n-2)%mod*(m-1)%mod*(m-2)%mod)%mod; 
	cout<<(a+b+c)%mod;
	} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章