刷题总结——路径(ssoi)
题目:
题目背景
CF 57D
题目描述
小美今天和她的好朋友在玩捉迷藏游戏。
地图可以抽象成一张 n*m 的图,地图上有一些障碍。
但这些障碍有一些性质:
1:每个障碍周围 8 个格子是没有障碍的。
2:每行每列最多只有一个障碍。
每次小美会躲在一个空地上,而她的朋友小芳会在一个空地出发寻找小美。
小美想知道如果每次小芳走 4 方向的最短路来抓她,而她们俩每次都各随机选一个空地,这个路径的平均长度是多少?
输入格式
输入第一行两个整数 n 和 m 。
接下来 n 行,每行一个长为 m 的字符串表示地图。
‘.’ 表示空地,‘X’ 表示障碍。
输出格式
输出一个小数表示平均路径长度。
样例数据 1
样例数据 2
备注
【数据规模】
对于 30% 的数据:n,m≤50;
对于 100% 的数据:2≤n,m≤1000。
题解:
先算竖直方向总共走的路程再算水平方向,注意算出多的路径*2;
另外别被longlong教做人
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=1005; char s[N]; int totx=0,n,m,liex[N],hangx[N]; long long findans(int n,int m,int a[]) { long long res=0; for(int i=1;i<=n;i++) { long long sig=0,tot=m-a[i]; for(int j=1;j<=n;j++) if(a[j])sig+=(m-1)*abs(i-j); else sig+=m*abs(i-j); if(a[i])res+=(m-1)*sig; else res+=m*sig; if(a[i]) { int l=i-1,r=i+1; while(a[l]>a[l+1]) tot+=m-a[l],l--; while(a[r]>a[r-1]) tot+=m-a[r],r++; res+=4*tot*(a[i]-1); } } return res; } int main() { //freopen("a.in","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%s",s); for(int j=1;j<=m;j++) if(s[j-1]=='X') { hangx[i]=j; liex[j]=i; totx++; } } int tot=n*m-totx; double ans=(findans(n,m,hangx)+findans(m,n,liex))*1.0/tot/tot; printf("%0.6lf",ans); return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步