三元組加強版
Problem
題目描述
給定兩個整數 \(n,m\) 問有多少三元組 \((x,y,z)\) 滿足:
- \(0\le x,y,z\le n\)
- \(x+y+z=m\)
輸入格式
一行給出兩個整數 \(n,m\) 。
輸出格式
一個整數,代表答案。
Example&Prompt
輸入輸出樣例
樣例\(1\):
輸入:$2\ 2\ \ \ $ 輸出:\(6\)
樣例\(2\):
輸入:$3\ 15\ $ 輸出:\(1\)
資料範圍
對於\(20\%\)的資料,滿足\(1\le n\le 100\)。
對於\(50\%\)的資料,滿足\(1\le n\le 10^4\)。
對於\(100\%\)的資料,滿足\(1\le n\le 10^7,0\le m\le3n\)
Solution1(20pts)
暴力列舉\(x,y,z\),再判斷合不合法,時間複雜度為\(O(n^3)\)。
Solution2(50pts)
暴力列舉\(x,y\),根據條件\(2\)算出\(z\),再判斷合不合法,時間複雜度為\(O(n^2)\)。
Solution3(100pts)
暴力列舉\(x\),再求出\(y,z\)的所有可能性。
那如何求\(y,z\)的所有可能性呢?不妨先令\(k=m-x\),因為條件\(1\),所以當\(k< 0\)時沒有合法的解,只要討論\(k\ge 0\)的情況。
首先先看一種簡單的情況:\(n\ge k\)
根據條件\(2\),我們有\(y+z=k\)
因此,我們就是要求兩個自然數之和為\(k\)的數量,這個很明顯是\(k+1\)種,舉個例子:
\[4=0+4=1+3=2+2=3+1=4+0 \]其實也就是\(k=i+(k-i)(0\le i\le k)\),共\(k+1\)種可能。
然後再看\(n<k\)的情況,我們依舊有\(y+z=k\),但此時可能有不合法結果,甚至沒有合法結果。
我們先設\(y=n\),此時\(z=k-n=m-2n\)為最小值,如果\(z>n\),那麼代表沒有合法結果,因為最小的可能也不符合要求,也就沒有符合要求的結果了。
然後考慮有不合法結果也有合法結果,根據上面的例子\(4\)
很明顯,從\(k=i+(k-i)(0\le i\le k)\)可以看出\(i>n\)不符合情況的數量是\(k-n\),\(k-i\)不符合情況的數量也是\(k-n\)(正好與\(i\)不符合情況相反)。
總情況仍是\(k+1\),因此,這時候符合情況的數量就是\(k+1-(k-n)* 2=2n-k+1\)。
我們把所有情況加起來就是答案了,時間複雜度為\(O(n)\)。
Code
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,ans=0;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++)
{
int k=m-i,j=0;
if(k>=0)
{
if(k>n)
{
if(k-n>n)
j=0;
else
j=2*n-k+1;
}
else
j=k+1;
}
ans+=j;
}
printf("%d",ans);
return 0;
}