HDU 6052 To my boyfriend 思維 + 列舉(計數)
阿新 • • 發佈:2019-02-05
題意:給出一個n*m的矩陣,每個點有一種顏色,定義矩陣的val為矩陣中不同顏色的數量,問任意一個子矩陣的val的期望為多少。
思路:我是直接看了一篇講解的想不理解都難的部落格:點選開啟連結
程式碼:
#include<bits/stdc++.h> #define ll long long #define pb push_back #define fi first #define se second #define pi acos(-1) #define inf 0x3f3f3f3f #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define rep(i,x,n) for(int i=x;i<n;i++) #define per(i,n,x) for(int i=n;i>=x;i--) using namespace std; typedef pair<int,int>P; const int MAXN=10010; int gcd(int a,int b){return b?gcd(b,a%b):a;} int n, m; vector<P> color[MAXN]; vector<int> Y[110]; int last[110]; ll calc(int col) { ll ans = 0; memset(last, 0, sizeof(last)); for(int o = 0; o < color[col].size(); o++) { int tx = color[col][o].fi, ty = color[col][o].se; for(int i = 1; i <= m; i++) Y[i].clear(); for(int i = 1; i <= m; i++) if(last[i]) Y[last[i]].pb(i); int tl = 1, tr = m; bool flag = 0; for(int i = tx; i >= 1; i--) { for(int j = 0; j < Y[i].size(); j++) { int tmp = Y[i][j]; if(tmp < ty) tl = max(tl, tmp + 1); else if(tmp > ty) tr = min(tr, tmp - 1); else { flag = 1; break; } } if(flag) break; ans += 1ll * (n - tx + 1) * (ty - tl + 1) * (tr - ty + 1); } last[ty] = tx; } return ans; } int main() { int T, c; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); for(int i = 0; i <= n * m; i++) color[i].clear(); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d", &c), color[c].pb(P(i, j)); for(int i = 0; i <= n * m; i++) if(color[i].size()) sort(color[i].begin(), color[i].end()); ll sum = 0, ans = 0; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) sum += 1ll * i * j; for(int i = 0; i <= n * m; i++) if(color[i].size()) ans += calc(i); printf("%.9lf\n", (double)ans * 1.0 / sum); } return 0; }