【BZOJ 1088 扫雷Mine】模拟

简介: http://www.lydsy.com/JudgeOnline/problem.php?id=1088 2*N的扫雷棋盘,第二列的值a[i]记录第 i 个格子和它8连通的格子里面雷的数目。 第一列的雷可能有多种方案满足第二列的数的限制,根据第二列的信息确定第一列雷有多少种摆放方案。

http://www.lydsy.com/JudgeOnline/problem.php?id=1088

2*N的扫雷棋盘,第二列的值a[i]记录第 i 个格子和它8连通的格子里面雷的数目。

第一列的雷可能有多种方案满足第二列的数的限制,根据第二列的信息确定第一列雷有多少种摆放方案。

设第一列的值为b[i],不难得出以下递推关系

b[0] + b[1] = a[0]

b[0] + b[1] + b[2] = a[1]

...

b[i] = a[i-1] - a[i-2] + b[i-3]
或 b[i] = a[i-1] - b[i-1] - b[i-2]

由此发现,b[0]、b[1]确定了,后续的b[i]也由递推式唯一的确定了。而又有b[0]+b[1] = a[0]的限制条件,故可根据a[0]的值枚举b[0], b[1]的组合,然后顺次求出b[i], 判断每个b[i]值是否合法,一旦发现不合法,则此种枚举情况不成立。

程序流程图如下(这里的“合法”判断与具体位置有关,如a[0], a[n-1] <3, a[n-1] == b[n-1] + b[n-2]):

代码如下(为了直观表达流程图,用了goto语句):

 1 #include <cstdio>
 2 using namespace std;
 3 
 4 int n;
 5 int a[10005];
 6 int b[10005];
 7 
 8 int main()
 9 {
10     scanf("%d", &n);
11     for(int i=0; i<n; i++){
12         scanf("%d", &a[i]);
13     }
14     int cnt = 0;
15 
16     for(int i=0; i<n; i++){ //非法 
17         if(a[i]<0 || a[i]>3){
18             goto L;
19         }
20     }
21     if(a[n-1]==3 || a[0] == 3){ //非法 
22         goto L;
23     }
24     
25     if(a[0] == 0) b[0] = b[1] = 0;
26     else if(a[0] == 2) b[0] = b[1] = 1; 
27     
28     if(a[0] == 1) goto B;
29     
30     b[2] = a[1] - a[0]; //0或2的情况 
31     if(b[2] < 0 || b[2] > 1){
32         goto L;
33     }
34     for(int i=3; i<n; i++){
35         b[i] = a[i-1] - a[i-2] + b[i-3];
36         if(b[i] < 0 || b[i] > 1){
37             goto L;
38         }
39     }
40     if(b[n-1] + b[n-2] != a[n-1]) //检查最后一个a 
41         goto L;
42     printf("1\n");
43     return 0;    
44 
45 B:    b[0] = 0; b[1] = 1; //01或10的情况 
46     b[2] = a[1] - a[0];
47     if(b[2] < 0 || b[2] > 1){
48         goto L1;
49     }
50     for(int i=3; i<n; i++){
51         b[i] = a[i-1] - a[i-2] + b[i-3];
52         if(b[i] < 0 || b[i] > 1){
53             goto L1;
54         }
55     }
56     if(b[n-1] + b[n-2] != a[n-1])
57         goto L1;
58     cnt++;
59         
60 L1:    b[0] = 1; b[1] = 0; //试探另一种 
61     b[2] = a[1] - a[0];
62     if(b[2] < 0 || b[2] > 1){
63         goto L;
64     }
65     for(int i=3; i<n; i++){
66         b[i] = a[i-1] - a[i-2] + b[i-3];
67         if(b[i] < 0 || b[i] > 1){
68             goto L;
69         }
70     }
71     if(b[n-1] + b[n-2] != a[n-1])
72         goto L;
73     cnt++;
74         
75 L:    printf("%d\n", cnt);
76     return 0;
77 
78 }
BZOJ 1088

 

目录
相关文章
|
SpringCloudAlibaba 监控 算法
SpringCloud Alibaba系列(三) Sentinel流控
  流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
247 0
SpringCloud Alibaba系列(三) Sentinel流控
|
12月前
|
运维 NoSQL 测试技术
从一个事故中理解Redis(几乎)所有知识点
作者从一个事故中总结了Redis(几乎)所有的知识点,供大家学习。
341 12
|
11月前
|
NoSQL API Redis
Redis
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
196 16
|
11月前
|
缓存 NoSQL 中间件
redis高并发缓存中间件总结!
本文档详细介绍了高并发缓存中间件Redis的原理、高级操作及其在电商架构中的应用。通过阿里云的角度,分析了Redis与架构的关系,并展示了无Redis和使用Redis缓存的架构图。文档还涵盖了Redis的基本特性、应用场景、安装部署步骤、配置文件详解、启动和关闭方法、systemctl管理脚本的生成以及日志警告处理等内容。适合初学者和有一定经验的技术人员参考学习。
730 7
|
10月前
|
监控 API 开发者
Sentinel:微服务的全能守护
Sentinel 是阿里巴巴开源的一款轻量级流量控制和熔断降级框架。它通过设置流量控制、熔断降级和系统保护规则,确保微服务在高并发场景下稳定运行。Sentinel 提供丰富的功能、实时监控和灵活的集成方式,适用于各种分布式系统。
1411 0
|
11月前
|
缓存 NoSQL 网络协议
【Azure Redis】因为Redis升级引发了故障转移后的问题讨论
3:对于Redis的Server Load指标,每秒创建连接数的并发值,是否有建议呢? 【答】:为了避免将缓存推到 100% 服务器负载,建议将连接创建速率保持在每秒 30 个以下。
106 0
|
监控 Java Nacos
SpringCloud基础5——微服务保护、Sentinel
sentinel、雪崩问题、流量控制、隔离和降级、授权规则、规则持久化
SpringCloud基础5——微服务保护、Sentinel
|
Ubuntu Linux Python
可以使用阿里云提供的Linux云主机,然后在其上安装银河麒麟v10sp1
可以使用阿里云提供的Linux云主机,然后在其上安装银河麒麟v10sp1
1679 1
|
存储 监控 NoSQL
揭秘Redis慢查询:这个工具将彻底改变你的性能优化策略!
【8月更文挑战第8天】在互联网应用中,数据库性能常成瓶颈。Redis作为高速内存数据库亦可能遭遇慢查询问题。本文探讨慢查询成因与解决方法。首先定义慢查询及其影响因素,随后介绍Redis内置的慢查询日志功能,通过配置`slowlog-log-slower-than`与`slowlog-max-len`来监控执行时间过长的命令。利用`SLOWLOG get`命令分析日志,定位性能瓶颈所在。以`LRANGE`命令为例,提出数据结构调整、使用流水线、限制返回元素数量、异步执行及优化内存使用等策略。最终实现Redis性能提升,确保应用流畅运行。性能优化需持续监控、分析与调整。
410 1
|
消息中间件 弹性计算 运维
对比阿里云的SofaMQ与RocketMQ
对比阿里云的SofaMQ与RocketMQ
2098 2