[ICPC2014 WF] Pachinko

题面翻译

题目描述

有一个宽度为 \(w\) 高度为 \(h\) 的方格纸, $ w \times h$ 的格子中,有一些是空的,有一些是洞,有一些是障碍物。从第一行的空的格子中随机选一个放置一个球,向上下左右移动的概率比为 \(p_u : p_d : p_l : p_r\) (满足 \(p_u + p_d + p_l + p_r = 100\)),不能移动到有障碍物的格子上。对于每个洞,输出落入该洞的概率。 \(w \le 20; h \le 10000\) 。保证第一行没有洞。

输入格式

第一行两个整数表示 \(w, h\) 。

第二行四个整数表示 \(p_u, p_d, p_l, p_r\) 。

接下来有一个 \(h\) 行 \(w\) 的字符矩阵,其中 . 表示空,X 表示障碍物,T 表示洞。

输出格式

若干行,每一行一个整数,按照矩阵从上到下,从左到右的顺序,输出每个洞的答案。绝对误差不超过 \(10 ^ -6\) 即为正确。

题目描述

You have been hired by Addictive Coin Machines to help design the next hit in their line of eye-catching, coin-guzzling, just-one-more-try Pachinko machines for casinos around the world.

Playing a Pachinko machine involves launching balls into a rectangular grid filled with pegs, obstacles, and targets. The ball bounces around the grid until it eventually hits one of the targets. The player earns a certain number of points depending on which target is hit.

The grid pattern for the next Pachinko machine has already been designed, but point values for the targets have not been assigned. These must be set so that like all casino machines, the machine is profitable but not too profitable. Thus it is important to figure out the probability of a ball hitting any particular target. That’s your job!

For simplicity, the grid is modeled as a tall rectangle filled with mostly-open spaces (each represented by ‘.’), impassable obstacles (each represented by ‘X’), and targets (each represented by ‘T’).

A ball is launched randomly with uniform probability into one of the mostly-open spaces on the top row of the grid. From that point on, collisions with pegs cause the ball to randomly bounce up, down, left, or right, with various given probabilities. For simplicity, assume these probabilities are the same for every space in the grid. If the ball bounces into an obstacle or attempts to move off the grid, it won’t actually move from its current space. When the ball moves into a target it is removed from play.

You can safely assume that the average number of spaces visited by a ball before hitting a target will not exceed \(10^{9}\). It would not make for a very enjoyable game if the ball just bounces forever!

For each target, calculate the probability that it is the one hit by a launched ball.

输入格式

The input consists of a single test case. The first line contains integers \(w\) and \(h\), which are the width and height of the Pachinko grid (\(1 \leq w \leq 20\) and \(2 \leq h \leq 10\, 000\)). The next line contains four non-negative integers \(u\), \(d\), \(l\), and \(r\), which sum to 100 and are the percentage probabilities of the ball bouncing up, down, left, or right from any open space.

Each of the next \(h\) lines contains \(w\) characters, each of which is ‘.’, ‘X’, or ‘T’. These lines describe the Pachinko grid. The first line, which describes the top row of the grid, contains at least one ‘.’ and no ‘T’s.

输出格式

Display one line for each ‘T’ in the grid, in order from top to bottom, breaking ties left to right. For each target, display the probability that a launched ball will hit it. Give the answer with an absolute error of at most \(10^{-6}\).

样例 #1

样例输入 #1

3 2
20 20 20 40
X.X
T.T

样例输出 #1

0.333333333
0.666666667

样例 #2

样例输入 #2

4 5
12 33 28 27
....
.XX.
....
T..T
XTTX

样例输出 #2

0.435853889
0.403753221
0.081202502
0.079190387

提示

Time limit: 5000 ms, Memory limit: 1048576 kB.

高斯消元? \((nm^3)\) 会直接寄掉。

然后发现如果把一个点 \(i,j\) 标号为 \(i*m+j\) 的话,那么点 \(s\) 只会在 \(s\pm m\) 以内才会有值。(听说这种矩阵叫 Band-Matrix)

消元时可以只消第 \(i\) 行上下 \(m\) 行,消元时也只消有元的那 \(m\) 列,复杂度是 \(O(nm^3)\)

注意消元时如果使用高斯-约旦消元的话,那么会破坏矩阵性质,要用有会带的那种消元。

在记录的时候可以把矩阵 \(i\) 行 \(j\) 列记到 \(i,j-i+m\),这样子就只用记录 \(2nm\) 个值。

在矩阵消元时如果遇到 0,当且仅当这个点和第一行不连通,可以 continue 掉。回代时也是,输出时可能要特判。

#include<bits/stdc++.h>
using namespace std;
const int N=21,M=10005;
const double eps=1e-9;
int n,m,c;
char s[M][N];
double u,d,l,r,mp[N*M][N*4],ans[N*M],p;
int main()
{
scanf("%d%d%lf%lf%lf%lf",&m,&n,&u,&d,&l,&r);
for(int i=1;i<=n;i++)
scanf("%s",s[i]+1);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(s[i][j]=='X')
mp[(i-1)*m+j][m]=1;
else
{
if(i==1)
++c;
double g=0;
if(s[i][j]=='.')
{
if(i^n&&s[i+1][j]^'X')
g+=d;
if(i^1&&s[i-1][j]^'X')
g+=u;
if(j^1&&s[i][j-1]^'X')
g+=l;
if(j^m&&s[i][j+1]^'X')
g+=r;
if(i^n&&s[i+1][j]^'X')
mp[i*m+j][0]=d/g;
if(i^1&&s[i-1][j]^'X')
mp[(i-2)*m+j][2*m]=u/g;
if(j^1&&s[i][j-1]^'X')
mp[(i-1)*m+j-1][m+1]=l/g;
if(j^m&&s[i][j+1]^'X')
mp[(i-1)*m+j+1][m-1]=r/g;
}
mp[(i-1)*m+j][m]=-1;
}
}
}
for(int i=1;i<=m;i++)
if(s[1][i]=='.')
ans[i]=-1.0/c;
for(int i=1;i<=n*m;i++)
{
// printf("%lf",mp[i][m]);
if(fabs(mp[i][m])<=eps)
continue;
// printf("%lf",mp[i][m]);
for(int j=i+1;j<=min(i+m,n*m);j++)
{
double s=mp[j][m-j+i]/mp[i][m];
for(int k=m;k<=2*m;k++)
mp[j][k-j+i]-=s*mp[i][k];
ans[j]-=ans[i]*s;
}
}
for(int i=n*m;i;i--)
{
for(int j=i+1;j<=min(i+m,n*m);j++)
ans[i]-=mp[i][m+j-i]*ans[j];
if(fabs(mp[i][m])>eps)
ans[i]/=mp[i][m];
else
ans[i]=0;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(s[i][j]=='T')
printf("%.10lf\n",ans[(i-1)*m+j]),p+=ans[(i-1)*m+j];
assert(fabs(1-p)<=eps);
}

[ICPC2014 WF] Pachinko的更多相关文章

  1. 题解 P6892 [ICPC2014 WF]Baggage

    解题思路 非常好的一道构造题. 在手动模拟几个样例(也许不止几个)之后呢. 就可以发现其实这些操作的开始以及最后几步是有相通之处的. 关于手动模拟的样例放在了文章末尾,需要的自取. 先考虑操作次数. ...

  2. 转《WF编程》笔记目录

    <WF编程>笔记目录 2008-03-18 09:33 by Windie Chai, 26803 阅读, 49 评论, 收藏, 编辑 WF笔记开始 <WF编程>系列之0 - ...

  3. wf(七)(手把手包会)

    这个demo中我们将用If/Else逻辑加到工作流用来展示不同的message通过自定义的条件. 如果name的字符数是奇数,第一个单词就输出“Greeting”否则输出“Hello”. 1. 在Sa ...

  4. wf(五)

    测试工作流: 运用wf(四)的solution: 创建单元测试项目: 1.选择HelloWorkflow解决方案,右键选择添加新建项目:选择单元测试模板,命名为HelloWorkflow.Tests. ...

  5. wf(四)

    我们已经在c#和xaml上编写了工作流,或者有的人会觉得在xaml上编写的workflow没什么优点,然而其实xaml其实具有一些很特别的优势. 1. xaml支持工作流设计器,c#不支持: 2. x ...

  6. wf(三)

    前言: 到现在我们可以看到,WF4包含一个.xmal 文件的设计器和一个调用活动的runtime.当你创建自己的工作流的时候,你是同时也创建了一个活动, 因为活动是一个继承System.Activit ...

  7. WF(二)

    步骤一: 运用WF(一)中创建好的solution 重命名Workflow1.xaml,变为SayHello.xaml 并在属性窗口设置名称为HelloWorkflow.SayHello,如下图: ( ...

  8. [WF] Quickstart Sample

    [WF] Quickstart Sample 前言 Workflow Foundation(WF),总是给人一种很有用.可是却不知道怎么用的印象.这主要是因为前置的功课太多.要整合很多底层知识,才能完 ...

  9. CS中调用微软自带com组件实现音频视频播放(wf/wpf)

    1.mp3播放器:工具箱中右键,在弹出的菜单中选择“选择项”,添加“com组件”,选择名称“windows Media Player",点击确定就会在工具箱新增一个“windows Medi ...

  10. WF 快速入门

    WF(Windows Workflow Foundation ,中文译为:Windows工作流基础)是一种基于更高级抽象概念的编程语言,适合于实现业务流程.虽然可以通过使用图形化的工具(Workflo ...

随机推荐

  1. [MAUI]在.NET MAUI中实现可拖拽排序列表

    .NET MAUI 中提供了拖放(drag-drop)手势识别器,允许用户通过拖动手势来移动控件.在这篇文章中,我们将学习如何使用拖放手势识别器来实现可拖拽排序列表.在本例中,列表中显示不同大小的磁贴 ...

  2. 带你快速上手HetuEngine

    本文分享自华为云社区<[手把手带你玩转HetuEngine](一)HetuEngine快速上手>,作者:HetuEngine九级代言. HetuEngine是什么 HetuEngine是华 ...

  3. 「学习笔记」扩展 KMP(Z 函数)

    对于个长度为 \(n\) 的字符串 \(s\).定义 \(z[i]\) 表示 \(s\) 和 \(s[i,n-1]\)(即以 \(s[i]\) 开头的后缀)的最长公共前缀(LCP)的长度.\(z\) ...

  4. ETL之apache hop系列4-hop开发数据增量同步功能

    ETL增量数据抽取CDC 概念:Change Data Capture,变化的数据捕获,也称:[增量数据抽取](名词解释) CDC是一种实现数据的增量抽取解决方案,是实现[ETL整体解决方案]中的一项 ...

  5. datetime去除时分秒

    datetime.datetime.now().replace(microsecond=0)

  6. SSMS 显示行号

    SSMS 显示行号 SSMS2022--工具--选项--文本编辑器--所有语言--常规--勾选"行号"--确定.

  7. Electron包装网站的问题

    原文链接 原文链接 Preface 最近尝试了很多不错的在线工具,只是每次都要进入网站,有点麻烦,于是想到之前了解过的electron,尝试一下打包成本地应用. Contents 1.下载所有源文件 ...

  8. 「codeforces - 1481F」AB Tree

    link. 理一下逻辑,主要讲一下我做题时的疑惑和其它题解没提到的细节. 首先容易看到,一个必然不劣的贪心策略是把尽量靠近根的层铺成同样的字符.也许会有疑惑,字符串是否本质不同的判定每个位置地位相等. ...

  9. C++ RAII在HotSpot VM中的重要应用

    RAII(Resource Acquisition Is Initialization),也称为"资源获取就是初始化",是C++语言的一种管理资源.避免泄漏的惯用法.C++标准保证 ...

  10. 洛谷题解 | P1046 陶陶摘苹果

    ​ 目录 题目描述 输入格式 输出格式 输入输出样例 说明/提示 题目思路 AC代码 题目描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 10 个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶 ...