[ICPC2014 WF] Pachinko
[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的更多相关文章
- 题解 P6892 [ICPC2014 WF]Baggage
解题思路 非常好的一道构造题. 在手动模拟几个样例(也许不止几个)之后呢. 就可以发现其实这些操作的开始以及最后几步是有相通之处的. 关于手动模拟的样例放在了文章末尾,需要的自取. 先考虑操作次数. ...
- 转《WF编程》笔记目录
<WF编程>笔记目录 2008-03-18 09:33 by Windie Chai, 26803 阅读, 49 评论, 收藏, 编辑 WF笔记开始 <WF编程>系列之0 - ...
- wf(七)(手把手包会)
这个demo中我们将用If/Else逻辑加到工作流用来展示不同的message通过自定义的条件. 如果name的字符数是奇数,第一个单词就输出“Greeting”否则输出“Hello”. 1. 在Sa ...
- wf(五)
测试工作流: 运用wf(四)的solution: 创建单元测试项目: 1.选择HelloWorkflow解决方案,右键选择添加新建项目:选择单元测试模板,命名为HelloWorkflow.Tests. ...
- wf(四)
我们已经在c#和xaml上编写了工作流,或者有的人会觉得在xaml上编写的workflow没什么优点,然而其实xaml其实具有一些很特别的优势. 1. xaml支持工作流设计器,c#不支持: 2. x ...
- wf(三)
前言: 到现在我们可以看到,WF4包含一个.xmal 文件的设计器和一个调用活动的runtime.当你创建自己的工作流的时候,你是同时也创建了一个活动, 因为活动是一个继承System.Activit ...
- WF(二)
步骤一: 运用WF(一)中创建好的solution 重命名Workflow1.xaml,变为SayHello.xaml 并在属性窗口设置名称为HelloWorkflow.SayHello,如下图: ( ...
- [WF] Quickstart Sample
[WF] Quickstart Sample 前言 Workflow Foundation(WF),总是给人一种很有用.可是却不知道怎么用的印象.这主要是因为前置的功课太多.要整合很多底层知识,才能完 ...
- CS中调用微软自带com组件实现音频视频播放(wf/wpf)
1.mp3播放器:工具箱中右键,在弹出的菜单中选择“选择项”,添加“com组件”,选择名称“windows Media Player",点击确定就会在工具箱新增一个“windows Medi ...
- WF 快速入门
WF(Windows Workflow Foundation ,中文译为:Windows工作流基础)是一种基于更高级抽象概念的编程语言,适合于实现业务流程.虽然可以通过使用图形化的工具(Workflo ...
随机推荐
- CF939F Cutlet 题解
题意简述 有一个正反面都为 \(0\) 的卡片,每过 \(1\) 分朝下那一面的数值就会增加 \(1\),你可以在几个区间的时间内翻转卡片,求经过 \(2n\) 秒后能否让这个卡片的正反面的数都为 \ ...
- 命令行安装ipa包
我们可以通过ssh连接我们的iphone,来使用命令行安装ipa包 itunnel_mux.exe --lport 9993 --iport 22 itunnel_mux.exe --lport 99 ...
- 修复linux系统更新后Conky无法启动的问题
kali系统更新后的版本为 ~$uname -a Linux 4rk 5.9.0-kali5-amd64 #1 SMP Debian 5.9.15-1kali1 (2020-12-18) x86_64 ...
- 如何使用Vite创建Vue3的uniapp项目
项目结构 my-vue3-project ├─ .env //默认环境变量 ├─ .env.development //开发环境变量 ├─ .eslintrc-auto-import.json //( ...
- HTML一键打包EXE工具1.9.9发布 (包含最新版下载地址)
HTML一键打包EXE工具(HTML封装EXE,桌件)是一款能将任意HTML项目(网址)打包为单个EXE文件的工具,无需依赖浏览器和服务器,直接双击即可运行.该工具支持多种HTML项目类型,包括KRP ...
- JNI动态注册以及JNI签名
一.动态注册和静态注册 注册native方法有两种方式,动态注册和静态注册.静态注册是在编译时进行注册,而且在java中声明的native方法和c/c++中的本地方法的对应关系是恒定的:比如说在com ...
- Record -「NOIP-S 2020」赛后总结
不是特别想说伤心的事情. T1 一遍过完所有大样例,此时只过去了十几二十分钟,不过之前花了半个小时通读了整个 PDF 所以此时大概过了 1h. T2 大概花了十几分钟胡出了一个反着枚举就是正解的 n^ ...
- 使用mtrace追踪JVM堆外内存泄露
原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明. 简介 在上篇文章中,介绍了使用tcmalloc或jemalloc定位native内存泄露的方法,但使用这个方法相 ...
- Go接口 - 构建可扩展Go应用
本文深入探讨了Go语言中接口的概念和实际应用场景.从基础知识如接口的定义和实现,到更复杂的实战应用如解耦与抽象.多态.错误处理.插件架构以及资源管理,文章通过丰富的代码示例和详细的解释,展示了Go接口 ...
- TOBO
然而并不会做. 最后就照着题解码了一遍/kk 真的好长啊.看时间就知道写了多久... upd in 2022: 我现在已经找不到原题面是什么了( 不过感觉把这样一篇不算题解的东西放进"题解& ...