【JZOJ 3053】 旅行

37 篇文章 0 订阅

Description

给定一个n行m列的字符矩阵,’.’代表空地,’X’代表障碍。移动的规则是:每秒钟以上下左右四个方向之一移动一格,不能进入障碍。
计算:在空地中随机选择起点和终点(可以重合,此时最短耗时为0),从起点移动到终点最短耗时的平均值。
每一行每一列至多有1个障碍,并且障碍不在对角线方向相邻。以下矩阵是不合法的:
.X
X.
2<=n,m<=1000

Analysis

对于一些特殊情况(无需绕行),答案就是各个点对坐标的绝对值之差。
可是可能会绕行,比如说:

.x.
(2,1)到(2,3)多走了两步。
怎么办?
由于矩阵有上述限制,我们手玩一下可以发现,要么绕行2步要么不绕行。
绕行的点对满足什么条件?
首先上述情况是一种。
III….
IIX…
II..X.
IX….
I….X
X…..
S…..
S到所有的I需要绕行,就这两种情况。自己总结吧。
唉,这结论题结论的==

Code

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int N=1010;
int n,m,num,r[N],c[N],sr[N],sc[N];
bool a[N][N];
int main()
{
    char ch;
    scanf("%d %d\n",&n,&m);
    fo(i,1,n)
    {
        fo(j,1,m)
        {
            scanf("%c",&ch);
            if(ch=='.') num++,a[i][j]=1,sr[i]++,sc[j]++;
            else r[i]=j,c[j]=i;
        }
        scanf("\n");
    }
    long long ans=0;
    fo(i,1,n-1)
        fo(j,i+1,n) ans+=2*(j-i)*sr[i]*sr[j];
    fo(i,1,m-1)
        fo(j,i+1,m) ans+=2*(j-i)*sc[i]*sc[j];
    fo(i,1,m)
        if(c[i])
        {
            int x=c[i]-1,y=n-c[i],nx=i,sum=0;
            ans+=x*y*4;
            if(c[i+1]>c[i])
            {
                for(;c[nx+1]>c[nx];sum+=m-c[++nx]);
                ans+=x*sum*4;
            }
            else
            {
                for(;c[nx+1] && c[nx+1]<c[nx];sum+=c[++nx]-1);
                ans+=y*sum*4;
            }
        }
    fo(i,1,n)
        if(r[i])
        {
            int x=r[i]-1,y=m-r[i],nx=i,sum=0;
            ans+=x*y*4;
            if(r[i+1]>r[i])
            {
                for(;r[nx+1]>r[nx];sum+=n-r[++nx]);
                ans+=x*sum*4;
            }
            else
            {
                for(;r[nx+1] && r[nx+1]<r[nx];sum+=r[++nx]-1);
                ans+=y*sum*4;
            }
        }
    printf("%.4lf",ans*1.0/num/num);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值