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 }
View Code
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
posted @ 2016-07-21 12:00  lbz007  阅读(151)  评论(0编辑  收藏  举报
Live2D