题目链接:Fishes
题意:
有一个n×m的鱼塘,有一张r×r的渔网,现在往池塘里面放k条鱼(每个格子只能放一条鱼), 现在撒网的地方是随机的(必须在池塘内),问能捕的鱼的期望值最大是多少?
题解:
这题dfs我是真的没想到。。因为怎么说,总是感觉这样有些暴力吧@。@# 要好好反思了。这题首先要把每个位置网覆盖的次数的公式推出来(用if else也行其实),因为可以发现最中间的位置一定最大,所以选取最中间的位置开始bfs,把遇到的点都放到优先队列中,这里对优先队列进行符号重载就可以很好地解决排序的问题,很值得学习。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAX_N = 1e5+9; 4 long long N,M,r,k; 5 struct P 6 { 7 long long first,second; 8 P(int x,int y){first = x,second = y;} 9 }; 10 priority_queue <P> que; 11 set<int> st[MAX_N]; 12 long long get_val(P t) 13 { 14 return (min(N - r + 1, t.first) - max(1ll, t.first - r + 1) + 1) * (min(M - r + 1, t.second) - max(1ll, t.second - r + 1) + 1); 15 } 16 bool operator < (const P &a,const P &b) 17 { 18 return get_val(b) > get_val(a); 19 } 20 21 int main() 22 { 23 while(cin>>N>>M>>r>>k) 24 { 25 while(!que.empty()) que.pop(); 26 for(int i=0;i<MAX_N;i++) st[i].clear(); 27 int x = (N+1)/2; 28 int y = (M+1)/2; 29 que.push(P(x,y)); 30 st[x].insert(y); 31 double ans = 0; 32 long long num = 0; 33 while(!que.empty()) 34 { 35 P t = que.top();que.pop(); 36 ans += (get_val(t)*1.0)/((N-r+1)*(M-r+1)*1.0); 37 k--; 38 if(!k) break; 39 //cout<<t.first<<"..."<<t.second<<"...."<<get_val(t)<<endl; 40 if(t.first+1>0 && t.first+1<=N && st[t.first+1].count(t.second) == 0) que.push(P(t.first+1,t.second)),st[t.first+1].insert(t.second); 41 if(t.first-1>0 && t.first-1<=N && st[t.first-1].count(t.second) == 0) que.push(P(t.first-1,t.second)),st[t.first-1].insert(t.second); 42 if(t.second-1 >0 && t.second-1 <=M && st[t.first].count(t.second-1) == 0) que.push(P(t.first,t.second-1)),st[t.first].insert(t.second-1); 43 if(t.second+1 >0 && t.second+1 <=M && st[t.first].count(t.second+1) == 0) que.push(P(t.first,t.second+1)),st[t.first].insert(t.second+1); 44 } 45 printf("%.10lf ",ans); 46 } 47 return 0; 48 }