2016 Multi-University Training Contest 1 T3
题目要求出所有合法点对间的最短路径的平均值,因此我们应当求出所有合法最短点对的最 短路径之和,再除以合法点对个数。
题目中Guard之间有着很不自然的制约关系,每个Guard的周围和同行、列都不能有其余的 Guard,但不可路过的格子却只有本身一格。由此发现,任意两点间的最短路径只会至多被 一个Guard所干扰。
我们可以先算出没有Guard制约的所有最短路径长度之和,再分别对于每个 Guard求出必须经过他的点对个数,原本必须经过它的最短路要多绕两格。
对于第i行每个#点,他对于上面第j行的每个#点在纵坐标路径长度的贡献是abs(i-j),列也一样。然后就可以o(n*m)的算出路径和。
对于G点,和他在同一列的和不同列的可以分开算。
1 #include<cstring> 2 #include<cstdio> 3 #define mem(a) memset(a,0,sizeof(a)) 4 int gl[1100],gh[1100],_,i,j,n,m; 5 double x,sum,ans,numl[1100],numh[1100],p; 6 char c[1100][1100]; 7 int main() 8 { 9 //freopen("1.in","r",stdin); freopen("1.out","w",stdout); 10 scanf("%d",&_); 11 while (_--) 12 { 13 sum=0; 14 mem(numh);mem(numl);mem(gl);mem(gh); 15 scanf("%d%d",&n,&m); 16 for (i=1;i<=n;i++) 17 { 18 scanf("%s",c[i]+1); 19 for (j=1;j<=m;j++) 20 { 21 if (c[i][j]=='#') 22 { 23 sum+=1; 24 numl[j]+=1; 25 numh[i]+=1; 26 } 27 else 28 { 29 gl[j]=i; 30 gh[i]=j; 31 } 32 } 33 } 34 ans=0;sum=sum*sum; 35 for (i=1;i<=n;i++) 36 { 37 for (j=1;j<i;j++) 38 { 39 x=(i-j)*numh[j]/sum; 40 ans+=x*numh[i]; 41 } 42 for (j=i+1;j<=m;j++) 43 { 44 x=(j-i)*numh[j]/sum; 45 ans+=x*numh[i]; 46 } 47 } 48 for (i=1;i<=m;i++) 49 { 50 for (j=1;j<i;j++) 51 { 52 x=(i-j)*numl[j]/sum; 53 ans+=x*numl[i]; 54 } 55 for (j=i+1;j<=m;j++) 56 { 57 x=(j-i)*numl[j]/sum; 58 ans+=x*numl[i]; 59 } 60 } 61 for (i=1;i<=n;i++) 62 for (j=1;j<=m;j++) 63 if(c[i][j]=='G') 64 ans+=((i-1)*(n-i)*4+(j-1)*(m-j)*4)/sum; 65 66 for (j=2;j<=n;j++){ 67 if (gh[j-1]==0 || gh[j]==0) continue; 68 if (gh[j-1]<gh[j]){ 69 p=(gh[j-1]-1)*(m-gh[j])/sum; 70 for (i=j-2;i>0;i--){ 71 if (gh[i]==0 || gh[i]>gh[i+1]) break; 72 p+=1.0*(gh[i]-1)*(m-gh[j])/sum; 73 } 74 }else { 75 p=(m-gh[j-1])*(gh[j]-1)/sum; 76 for (i=j-2;i>0;i--){ 77 if (gh[i]==0 || gh[i]<gh[i+1]) break; 78 p+=(m-gh[i])*(gh[j]-1)/sum; 79 } 80 } 81 ans+=4.0*p; 82 } 83 for (j=2;j<=m;j++){ 84 if (gl[j-1]==0 || gl[j]==0) continue; 85 if (gl[j-1]<gl[j]){ 86 p=(gl[j-1]-1)*(n-gl[j])/sum; 87 for (i=j-2;i>0;i--){ 88 if (gl[i]==0 || gl[i]>gl[i+1]) break; 89 p+=(gl[i]-1)*(n-gl[j])/sum; 90 } 91 }else { 92 p=(n-gl[j-1])*(gl[j]-1)/sum; 93 for (i=j-2;i>0;i--){ 94 if (gl[i]==0 || gl[i]<gl[i+1]) break; 95 p+=(n-gl[i])*(gl[j]-1)/sum; 96 } 97 } 98 ans+=4.0*p; 99 } 100 101 printf("%.4f\n",ans); 102 } 103 return 0; 104 }
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
17652872 | 2016-07-20 19:02:27 | Accepted | 5725 | 717MS | 2528K | 2012 B | G++ | lbz007 |
-------------------------------------------------------------------------
花有重开日,人无再少年