1. 程式人生 > 實用技巧 >2020牛客寒假演算法訓練營第一場題解(持續更新中)

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

根據矩陣快速冪我們可以很快的得到,但是這裡還有一點就是要利用費馬小定理