塔防(cover)

news/2024/12/22 19:35:23/

塔防(cover)Atcoder/CF的某道题

题目背景

在某个塔防游戏中,有一种防御塔,可以攻击到上下左右四个方向以及自身位置的敌人。

题目描述

塔防游戏的一个关卡地图可以看作一个 R × C R\times C R×C的矩阵,也就是 R R R行, C C C列的矩阵。

其中,用#代表障碍,用.代表地面。对于每个地面,都可以选择不放置防御塔,或者放置防御塔。每个防御塔能够攻击到自己所在位置的地面,同时,能攻击到自己位置上下左右四个射线方向上的敌人,攻击范围沿射线方向延伸。但是射线上如果有其他防御塔或者障碍,将会阻断攻击范围的延伸。

现在, N S H NSH NSH决定随机放置防御塔。也就是说,对每个地面位置,是否放置防御塔是等概率的。

请求出这样随机放置防御塔后,期望有多少个地面位置能处于防御塔的攻击范围之下。

输出一个整数作为答案,表示答案在模 1 0 9 + 7 10^9+7 109+7的意义下的结果。

输入格式

第一行,两个正整数 r r r c c c

接下来 r r r行,每行一个长度为 c c c的字符串(表示地图)。

输出格式

输出一个整数作为答案,表示答案在模 1 0 9 + 7 10^9+7 109+7的意义下的结果。

样例输入与输出

样例输入1

1 3
.#.

样例输出1

1

样例输入2

2 3
..#
#..

样例输出2

250000005

样例输入3

1 5
..#..

样例输出3

3

提示与说明

样例1解释

随机放置一共有 4 4 4种等概率可能:.#.t#..#tt#t,对应的攻击范围下的地面数量为 0 0 0 1 1 1 1 1 1 2 2 2。因此期望为 E = 0 + 1 + 1 + 2 4 m o d ( 1 0 9 + 7 ) = 1 E=\frac{0+1+1+2}{4}mod(10^9+7)=1 E=40+1+1+2mod(109+7)=1

数据范围

30 % 30\% 30%的数据满足 r × c ≤ 18 r\times c\leq 18 r×c18

60 % 60\% 60%的数据满足 r , c ≤ 200 r,c\leq 200 rc200

100 % 100\% 100%的数据满足 1 ≤ r , c ≤ 2000 1\leq r,c\leq 2000 1rc2000

时间限制:1s 空间限制:256MB

解题思路

首先我们来考虑什么情况下这个地面时不会被攻击到的:

每一个地面放置防御塔的概率都是 1 2 \frac{1}{2} 21,那么只有当上图中所有的.都是没有放置的防御塔的时候,中间的地面才不会被攻击到。所以我们可以算出这个点不被攻击到的概率是 1 2 8 \frac{1}{2^8} 281。其中分母代表的是这里相连通的点的个数的总情况数(比如说这里就有八个点)。

那么反过来说,这个点能够被攻击到的概率就是 1 − 1 2 8 = 2 8 − 1 2 8 1-\frac{1}{2^8}=\frac{2^8-1}{2^8} 1281=28281

最后,我们就只需要算出每个点的概率的和就是期望值了。

另一个考点:有理数取模

这道题里面给出的模数为 1 e 9 + 7 1e9+7 1e9+7,我们知道这个数是一个质数,那么这道题就比较好做了。

这道题中,我们只用求出逆元就可以了。我们先把分数 y x \frac{y}{x} xy转变为 y × x − 1 y\times x^{-1} y×x1,那么 x − 1 x^{-1} x1就是 x x x的逆元,那我们知道在模数为质数的情况下 x − 1 ≡ x p − 2 ( m o d p ) x^{-1}\equiv x^{p-2}(mod\ p) x1xp2(mod p)(费马小定理)。这样我们就可以算出有理数取模了( y x ≡ y × x p − 2 \frac{y}{x} \equiv y\times x^{p-2} xyy×xp2

总体思路就是这样了,下面是一些优化和具体实现。

优化

找到每一个点对应的行和列里面有多少个没有被挡住的地面有两种方法,第一种就是非常暴力的枚举每一个点,并求出对应的地面数量。这种做法可以过掉所有数据点(因为没有 h a c k hack hack)。然而,数据经过同学们的不屑努力下,发现当所有的点都是地面的时候,这种算法会完全的炸掉。那么我们就想办法优化他,我们没有必要每次都从枚举的当前点像四个方向找到所有的地面数量,我们只用在原图中找到所有的连续地列和行(一个点也算列和行),这样我们只需要 O ( 2 n m ) O(2nm) O(2nm)的复杂度就可以求出每一个点对应的地面总数(但是对于墙壁很多的数据点,会比朴素算法更慢,但是完全能过)。

然而发现优化后在老年评测机上还是会 T L E TLE TLE,我们继续优化,我们将 2 1 2^1 21 2 n × m 2^{n\times m} 2n×m的值预处理出来,不用每次都用快速幂算,这样成功的过掉了这道题

最后放上代码

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int read(){int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
void write(int x){if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10+'0');return ;
}
int qpow(int x,int up){int result=1;for(;up;up>>=1){if(up&1) result=(long long)result*x%mod;x=(long long)x*x%mod;}return result;
}
struct point{int h;int l;
}a[2005][2005];
int n,m,ans=0,pow2[4005];
char mmap[2005][2005],c;
int main(){freopen("cover.in","r",stdin);freopen("cover.out","w",stdout);for(int i=1;i<=4000;i++){pow2[i]=qpow(2,i);}n=read();m=read();	for(int i=1;i<=n;i++){c=getchar();while(c!='#'&&c!='.') c=getchar();mmap[i][1]=c;for(int j=2;j<=m;j++){mmap[i][j]=getchar();}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(a[i][j].h==0){bool flag1=0;int pos1=m;for(int k=j;k<=m;k++){if(mmap[i][k]=='#'){flag1=1;pos1=k;break;}}if(flag1==1){a[i][j].h=pos1-j;}else{a[i][j].h=pos1-j+1;}if(flag1==1){for(int k=j;k<pos1;k++){a[i][k].h=a[i][j].h;}}else{for(int k=j;k<=pos1;k++){a[i][k].h=a[i][j].h;}}}if(a[i][j].l==0){bool flag2=0;int pos2=n;for(int k=i;k<=n;k++){if(mmap[k][j]=='#'){flag2=1;pos2=k;break;}}if(flag2==1){a[i][j].l=pos2-i;}else{a[i][j].l=pos2-i+1;}if(flag2==1){for(int k=i;k<pos2;k++){a[k][j].l=a[i][j].l;}}else{for(int k=i;k<=pos2;k++){a[k][j].l=a[i][j].l;}}}int tt=a[i][j].h+a[i][j].l-1;ans=(ans+(long long)(pow2[tt]-1)*qpow(pow2[tt],mod-2)%mod)%mod;}}write(ans);return 0;
}

http://www.ppmy.cn/news/624521.html

相关文章

宝石塔防的贴吧地址:

宝石争霸吧 http://tieba.baidu.com/f?kw%B1%A6%CA%AF%D5%F9%B0%D4

宝石塔防:如果还有人过不去1337,俺来发个详细点儿的攻略吧

游戏版本建议1.17,贴吧里有破解版,因为这个版本有个让所有怪一次性出完的快捷键很好用 前期,100级以内,这个升级没什么难度,随便找一关,选无尽模式,不论你怎么造,尽量坚持,几十或100来波左右死就死掉了,然后经验一涨一大截,总结下来就是无尽模式巨型怪,你也可以把巨怪血弄高一…

宝石塔防攻略

宝石塔防小游戏攻略 (Gem Craft Game Guide) 作者&#xff1a;神马游戏原创 类型&#xff1a;策略 专题&#xff1a;经典 宝石 塔防 2011-04-18 宝石塔防小游戏攻略1&#xff1a; 五、最后一关BOSS攻略。必须打两轮。关键点&#xff1a;&#xff08;1&#xff09;后期…

宝石塔防3心得

心得   把重要的技能学满级后 多的技能点升级魔法上限 这样扩充魔法池的效果更好 更快   参考楼下的陷阱流 在出怪口放一个陷进 宝石用多重和吸魔双色合成宝石 周围尽可能的放满辅助塔 也放多重和吸魔的双色合成宝石&#xff08;初始魔法不多 辅助塔里宝石放小点的也行 主…

探索Python条件语句的奇妙世界:解密逻辑与控制流

文章目录 前言if 语句if ... else ...多重判断&#xff08;if ... elif ... else...&#xff09;if 嵌套猜数字游戏三目运算符 前言 Python的条件语句用来根据特定的条件决定程序的执行流程。它允许程序根据条件的真假执行不同的代码块&#xff0c;从而实现不同情况下的不同操…

I/O复用的高级应用三——同时处理TCP和UDP服务

截至目前学习&#xff0c;我们讨论过的服务器程序都只监听一个端口。但在实际应用中&#xff0c;有不少服务器程序能同时监听多个端口&#xff0c;比如超级服务inetd和android的调试服务adbd。 从bind系统调用的参数看&#xff0c;一个socket只能与一个socket地址绑定&#xff…

windows下优化笔记本性能——降低CPU使用率

最近发现待机时CPU使用率30%多&#xff0c;觉得有点高&#xff0c;于是打开资源管理器发现有个叫COM Surrogate的进程啥几把用没有还占了30%&#xff0c;于是就想办法把他杀掉。方法如下&#xff1a; 杀掉之后CPU使用率只有10%左右了.

提高CPU使用率

某些特殊时候&#xff0c;需要提升下cpu的利用率&#xff0c;此时……………………需要一个极其简单的脚本来完成&#xff01; #!/bin/bash while (true);do { for i in $(seq 100000 100100) do Xexpr $i \* 3 $i \* 9999; echo $X >> /tmp/a.txt; done echo "&qu…