數三角形(
******** counting, uva 11401
)有多少種方法可以從1,
2, 3,
…, n中選出
3個不同的整數, 使得以
它們為三邊長可以組成三角形? 比如n=
5時有3種方法, 即(2,
3,4) , (2,
3, 5) , (3,
4, 5) 。 n=
8時有22種方法。
【輸入格式】
輸入包含多組測試資料, 每組資料的第一行為整數n(
3≤n≤1000000
) 。 輸入用n<
3的標誌結束。
170【輸出格式】
對於每組資料, 輸出其方案總數。
【分析】
三重迴圈的時間複雜度為o(
n3) , 採用這種方法肯定超時。 這樣的
規模即使是o(
n2) 時間的演算法都很難承受, 那麼只能進行一些數學分析
了。用加法原理, 設最大邊長為
x的三角形有c(
x) 個, 另外兩條邊長分別為y
和z, 根據三角形不等式
[2]有y+
z>x。 所以
z的範圍是x-
y<z<
x。根據這個不等式, 當y=
1時x-
1<z<
x, 顯然無解; y=
2時只有乙個解(z
=x-1
) ; y=
3時有兩個解(z=
x-1或者
z=x-
2) ……直到y=
x-1時有
x-2個解。 根據等差數列求和公式, 一共有0+
1+2+
…+(x-
3)+(x
-2) =(x-
1) (x-
2) /2個解。
可惜, 這並不是c(
x) 的正確數值, 因為上面的解包含了y=
z的情況, 而且每個三角形算了兩遍(想一想, 為什麼) 。 解決方案很簡單,
首先統計y=
z的情況。
y的取值從
x/2+
1開始到x-
1為止, 一共有x-
1-x/2=(x-
1) /2個解, 然後把這部分解扣除, 再除以
2, 即
原題要求的實際上是
「最大邊長不超過
n的三角形數目」f(
n) 。 根據
加法原理, f(
n) =c(
1) +c(
2) +…+
c(n) 。 可以寫成遞推式f(
n) =f(
n-1) +c(
n) 。 **如下。
#includeusing namespace std;
long long f[1000010];
int main(){
f[3]=0;
for(long long x=4;x<=1000000;++x)
f[x]=f[x-1]+((x-1)*(x-2)/2-(x-1)/2)/2;
int n;
while(cin>>n&&n>=3) cout<
組合數問題 楊輝三角形 組合數
還好不是在考場上遇到這道題 我會說在這之前我都不記得有這麼乙個公式?總之蒟蒻的數論真的太差了 知道這個公式後一切都變的簡單了。先用o n m 預處理出c i j 在 裡寫的是f i j 的值,然後用二維字首和預處理出答案,在查詢時就可以o 1 回答啦!include include using na...
BZOJ1914 數三角形(組合數,計算幾何)
bzoj許可權題 良心洛谷 這種姿勢很吼啊,表示計算幾何啥的一竅不通來著。題目就是這樣,正難則反,所以我們不考慮過原點的三角形,反過來,總數減去不包含原點的三角形。這個怎麼計算呢?我們每次先確定乙個點,那麼,所有在這個點和原點的連線下方的點都是可行的,那麼極角排序之後發現這就是一段連續的區間,所以直...
2497 數三角形
題目描述 小b有乙個僅包含非負整數的陣列a,她想知道有多少個三元組 i,j,k 滿足i輸入 第一行輸入乙個正整數n,表示陣列a中元素個數 第二行n個非負整數,表示a中元素,以空格隔開 其中0 n 1000,a中任意元素a i 滿足0 a i 1000。輸出 輸出乙個數,表示滿足題意的三元組個數 輸入...