[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 ...
随机推荐
- 带你快速上手HetuEngine
本文分享自华为云社区<[手把手带你玩转HetuEngine](一)HetuEngine快速上手>,作者:HetuEngine九级代言. HetuEngine是什么 HetuEngine是华 ...
- ETL之apache hop系列4-hop开发数据增量同步功能
ETL增量数据抽取CDC 概念:Change Data Capture,变化的数据捕获,也称:[增量数据抽取](名词解释) CDC是一种实现数据的增量抽取解决方案,是实现[ETL整体解决方案]中的一项 ...
- 纯干货!一文get昇腾Ascend C编程入门全部知识点
本文分享自华为云社区<昇腾Ascend C编程入门教程>,作者:昇腾CANN . 2023年5月6日,在昇腾AI开发者峰会上,华为正式发布了面向算子开发场景的昇腾Ascend C编程语言. ...
- 原来你是这样的SpringBoot--Async异步任务
本节我们一起学习一下SpringBoot中的异步调用,主要用于优化耗时较长的操作,提高系统性能和吞吐量. 一.新建项目,启动异步调用 首先给启动类增加注解@EnableAsync,支持异步调用 @En ...
- charts自适应
大屏echarts自适应文字大小 1.在utils中创建 setFontSize.js function setFontSize(val) { const baseSize = 50; let sca ...
- HTML/网站一键打包APK工具(html网页打包安卓APP应用)
HTML一键打包APK工具使用说明 工具简介 HMTL一键打包APK工具可以把本地HTML项目或者网站打包为一个安卓应用APK文件,无需编写任何代码,也无需配置安卓开发环境,支持在最新的安卓设备上安装 ...
- 在微服务环境下,远程调用feign和异步线程存在请求数据丢失问题
一.无异步线程得情况下feign远程调用: 0.登录拦截器: @Component public class LoginUserInterceptor implements HandlerInterc ...
- 「joisc2016 - D3T2」回転寿司
题意大概是这样,「每次操作选出区间中的一个 LIS(strictly),满足其开端是极靠近左端点且大于 \(A\) 的位置,答案即这个 LIS 的末尾,做一个轮换后弹出序列末端」. 首先做几个观察. ...
- Solution -「SCOI 2016」萌萌哒
Description Link. 给定一个长度为 \(n\) 的数组让你填数,需要满足 \(m\) 个形如 \(([l_{1},r_{1}],[l_{2},r_{2}])\) 的要求,这两个区间填好 ...
- Solution -「ARC 103B」Robot Arms
Description Link. 给定 \(n\) 组坐标.构造长度为 \(m\) 的序列 \(\{c_n\}\) 和 \(n\) 组包含 LRUD 的路径,满足对于每一组坐标: \(c_i\) 表 ...