前兩題A得還挺快,終於分數又漲了一些。。。第三題求出了全部連通集的個數,才發現讓求的是全部連通集的大小之和,怎麼求大小之和還沒想到。ios
1001 DZY Loves Balls 這道題讓求出A大於B的機率,可是題目自己好像和機率關係不大,我見過讓求指望之類的機率題目,好像都比這個難一些。 一共N個球,取兩個,一共的取法是N * (N-1),這裏是把值相同的球也看作不一樣來想。 求A大於B的狀況的種類,咱們能夠對這N個值作一個筒排序,從小到大掃描,就能在線性複雜度內求出每一個值的球,比它小的有多少個球,累加這些值就好。spa
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int s[320]; int main() { int t; cin >> t; while(t--) { memset(s, 0, sizeof(s)); int n, a; scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%d", &a); s[a]++; } int presum = 0, p = 0; for(int i = 1; i <= 300; i++) { if(s[i]) p += s[i] * presum; presum += s[i]; } int q = n*(n-1); double ans = (double)p / q; printf("%.6f\n", ans); } return 0; }
1002 DZY Loves Partition 把n分解成k個不一樣的數的和,求這k個不一樣的數的最大乘積是多少。 若是n小於1到k的累和((1+k) * k / 2),那麼確定是無解的。code
若是n大於等於k,咱們能夠將n想象成從1加到k再加剩餘的部分(n-sum(1,k)),咱們只要把剩餘的值想辦法加到1到k的一些數中,知足最大乘積最大就好。排序
好比n = 30,k = 7: 1 + 2 + 3 + 4 + 5 + 6 + 7 這不夠n,還差2,咱們將2加到某些數上就好。 咱們將後2個數向後移一位是最划得來的,由於1到5不能移動(加2也不會超過7,這樣會重複),6+2=8和7+1=8且6+1=7是同樣的。ci
其實就是一個貪心策略,咱們總讓靠右邊的數優先加上1(即向右移動),再證實若是左邊的數加上某值獲得的結果不會比先前的策略好。string
#include <cstdio> #include <iostream> using namespace std; typedef long long lint; const int mod = 1000000007; int main() { int T; cin >> T; while(T--) { lint n, k; cin >> n >> k; lint l = ((1 + k) * k) / 2; if(n < l) { printf("-1\n"); continue; } lint a = 1, b = k; lint res = n - l; a += (res / k); b += (res / k); res %= k; lint ans = 1; lint o = b; while(o >= a) { if(res) { ans *= (o+1); res--; } else { ans *= o; } ans %= mod; o--; } cout << ans << endl; } return 0; }
代碼很簡單,注意到若是n-sum(1, k)剩下的值很大的話能夠除以n,獲得的商加到每一個數上,這樣咱們只須要記錄k個值的兩個端點就好。it