1. 笔记

题意是求距离的期望(距离仍指连接两点且有效的路径长度的最小值)。直观想象可以发现,该距离与曼哈顿距离相比最多多2(可以构造这样的路径)。

答案=(任意两点曼哈顿距离的总和 - 至少有一点是守卫的距离总和 + 因守卫的存在比曼哈顿距离多出的部分)/(任选两点均不是守卫的情况数)

任意两点曼哈顿距离的总和=\(\frac{mn(m+n)(mn-1)}{3}\),O(1)

至少有一点是守卫的距离总和:临时跑,O(n^2)

任选两点均不是守卫的情况数=非守卫点数^2,O(1)

比较tricky的是因守卫的存在比曼哈顿距离多出的部分。通过简单的实验可以得到这样一个猜想(实际上也是正确的):如果从左上走到右下,比如说从第一排第一列走到第n排第m列,那么需要绕路的必要条件是守卫的列数随着排数的增加而增加。证明如下:

设前k-1排都满足“守卫的列数随着排数的增加而增加”的性质,而第k排不满足,其中k>1。不难发现,一定可以从起点(1,1)走到第k排守卫的右侧一位(k,r)而不绕路(记(k,r)表示第k排第r列)。Claim:(k,r)开始走到终点也是不绕路的。要证明这一点,只要对列数从m到r做归纳,得出结论:从(k,r)走到终点(n,m)需要绕路,当且仅当长方形区域(k,r)-(n,m)内的每一列都必须有守卫,并且守卫的排布满足“守卫的列数随着排数的增加而增加”的性质。但这是不可能的,因为必有一个守卫会和前k-1排的某个守卫位于同一列。#

由此可以得出绕路的充要条件 ( 还是从左上走到右下):要么每一排、要么每一列都有一个守卫,并且守卫的排布满足“守卫的列数随排数的增加而增加”的性质。证明如下:

若第一排第一列都有守卫,由必要条件知,不需要绕路。若第一排或第一列有一个为空,则由必要条件的证明知,守卫的排布必满足上述性质。逆命题是显然的。#

实现时只要考虑满足“绕路性质”的守卫让多少条路径绕路即可。O(n^2)

总复杂度为O(n^2)。可以通过。

2. 代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
typedef long long ll;
int m,n;
ll a,b,c,d;
int l[maxn],r[maxn];
int main()
{
//freopen("Input.txt","r",stdin);
int T;scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
memset(l,0,sizeof l);memset(r,0,sizeof r);
char tmp[maxn];
int cnt=0;
//printf("Input:\n");
for(int i=1;i<=n;++i)
{
scanf("%s",tmp);
for(int j=0;j<m;++j)if(tmp[j]=='G'){l[i]=j+1;r[j+1]=i;cnt++;}
}
//printf("End\n");
a=1LL*m*n*(m+n)*(m*n-1)/3;
d=1LL*(m*n-cnt)*(m*n-cnt);
b=0;
for(int i=1;i<=n;++i)
{
if(l[i])b+=1LL*m*n*n-2*m*n*i+2*m*i*i+m*n-2*m*i+n*m*m-2*m*n*l[i]+2*n*l[i]*l[i]+m*n-2*n*l[i];
}
//printf("b=%d\n",b);
for(int i=1;i<=n;++i)
{
if(l[i])
{
for(int j=i+1;j<=n;++j)
{
if(l[j])b-=2*abs(i-j)+2*abs(l[i]-l[j]);
}
}
}
c=0;
for(int i=1;i<=n;++i)
{
if(l[i]==0)continue;
c+=4*(l[i]-1)*(m-l[i]);
int j=i+1;
while(j<=n&&l[j]&&l[j]>l[j-1])c+=4*(l[i]-1)*(m-l[j++]);
j=i+1;
while(j<=n&&l[j]&&l[j]<l[j-1])c+=4*(l[j++]-1)*(m-l[i]);
//printf("i=%d,c=%d\n",i,c);
}
for(int i=1;i<=m;++i)
{
if(r[i]==0)continue;
c+=4*(r[i]-1)*(n-r[i]);
int j=i+1;
while(j<=m&&r[j]&&r[j]>r[j-1])c+=4*(r[i]-1)*(n-r[j++]);
j=i+1;
while(j<=m&&r[j]&&r[j]<r[j-1])c+=4*(r[j++]-1)*(n-r[i]);
//printf("j=%d,c=%d\n",i,c);
}
double ans=a-b+c;
ans/=d;
printf("%.4f\n",ans);
}
}

HDU 5725 Game的更多相关文章

  1. hdu 3631 Shortest Path(Floyd)

    题目链接:pid=3631" style="font-size:18px">http://acm.hdu.edu.cn/showproblem.php?pid=36 ...

  2. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  3. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  4. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  5. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  6. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  7. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

  8. hdu 4481 Time travel(高斯求期望)(转)

    (转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...

  9. HDU 3791二叉搜索树解题(解题报告)

    1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...

随机推荐

  1. C 送外卖

    时间限制 : - MS   空间限制 : 365536 KB  评测说明 : 时限1000ms 问题描述 暑期期间,何老板闲来无事,于是买了辆摩托车,签约某团外卖,跑起来送外卖的业务.  何老板负责的 ...

  2. A. Remainder Codeforces Round #560 (Div. 3)

    A. Remainder Codeforces Round #560 (Div. 3) You are given a huge decimal number consisting of nn dig ...

  3. Java代理笔记

    代理顾名思义,就是一个中间层,当我们要使用某个方法时,不直接调用,而是告诉代理,让代理替我们去请求方法,并返回结果.在这个过程中,我们只知道代理执行并返回给了我们操作结果,至于它有没有其他操作并不知道 ...

  4. Unity 游戏框架搭建 2019 (二十七) 弃用的代码警告解决

    在前两篇,我们把所有的示例重头到尾整理了一遍. 当前的状态如下: 要做的事情: (完成) 备份:导出文件,并取一个合理的名字. 遗留问题: (完成) 第八个示例与之前的示例代码重复,功能重复. (完成 ...

  5. SQL Server 存储过程分页。

     create proc proc_Product@page int, -- 页数@row int --  一页有几行Asdeclare @newpage int  set @newpage = (@ ...

  6. Linux基础篇,系统服务(service)的管理

    一.服务是什么? 用白话文说,服务就是"常驻在内存中的进程",用来提供一些系统或网络功能. 二.service和daemon的区别与联系 因为服务(service)本质上来说也是程 ...

  7. 【java设计模式】(7)---策略模式(案例解析)

    策略模式 一.概念 1.理解策略模式 策略模式是一种行为型模式,它将对象和行为分开,将行为定义为 一个行为接口 和 具体行为的实现.策略模式最大的特点是行为的变化,行为之间可以相互替换. 每个if判断 ...

  8. 多角度让你彻底明白yield语法糖的用法和原理及在C#函数式编程中的作用

    如果大家读过dapper源码,你会发现这内部有很多方法都用到了yield关键词,那yield到底是用来干嘛的,能不能拿掉,拿掉与不拿掉有多大的差别,首先上一段dapper中精简后的Query方法,先让 ...

  9. AJ学IOS(36)UI之手势事件旋转_缩放_拖拽

    AJ分享,必须精品 效果 完成一个图片的捏合缩放,拖拽,旋转动作. 设计思路 拖拽: 首先是最简单的拖拽 //拖拽 -(void)panTest { UIPanGestureRecognizer *p ...

  10. 2019-07-31【机器学习】无监督学习之降维NMF算法 (人脸特征提取)

    代码 from numpy.random import RandomState #加载RandomState用于创建随机种子 import matplotlib.pyplot as plt from ...