【题目描述】
农夫约翰的奶牛们总是偷偷的逃出他的农场,去外面为非作歹。
农夫约翰为了防止它们私自逃离农场,购买了一个密码锁,以此阻止奶牛们打开农场大门。
约翰知道他的奶牛们都非常聪明,因此他想要确保它们不能通过简单的尝试一些密码组合,就轻易的将锁打开。
锁具上有三个密码拨盘,每个拨盘上的数字为1∼N1\sim N1∼N,其中111和NNN相邻(因为拨盘是圆形的)。
一共有两种可以打开密码锁的数字组合,一组是约翰设置的密码组合,一组是制造商设置的密码组合。
这种锁具有一定的容错性,只要三个表盘上的数字与任意一组正确密码组合的对应位置数字相距两个位置以内,锁均会打开。
例如,假设约翰设置的密码组合是(1,2,3)(1,2,3)(1,2,3),制造商设置的密码组合是(4,5,6)(4,5,6)(4,5,6)。
此时我们输入组合(1,3,5)(1,3,5)(1,3,5)就可以将锁打开,因为这与约翰设置的密码接近,输入组合(2,4,8)(2,4,8)(2,4,8)也可以将锁打开,因为这与制造商设置的密码接近。
但是,如果我们输入组合(1,5,6)(1,5,6)(1,5,6)就不能将锁打开,因为它和两个密码都不接近。
现在给定你两个设置好的密码,请你判断一共有多少种密码组合可以将锁打开。
注意,密码组合是有序的,因此(1,2,3)(1,2,3)(1,2,3)和(3,2,1)(3,2,1)(3,2,1)是两种不同的组合。

【输入格式】
第一行包含整数NNN。
第二行包含三个整数,表示约翰设置的密码组合。
第三行包含三个整数,表示制造商设置的密码组合。

【输出格式】
输出一个整数,表示可以打开锁的密码组合数量。

【数据范围】
1≤N≤1001≤N≤1001≤N≤100

【输入样例】

50
1 2 3
5 6 7

【输出样例】

249

【分析】


我们可以枚举所有密码组合,对于每种密码判断其是否满足与题中所给的任意密码接近,如果满足则答案加一,时间复杂度为O(n3)O(n^3)O(n3),本题数据量很小,因此可以过。

有没有优化的做法呢?假设题中所给的两个密码组合分别为aaa和bbb,如果N≥5N\ge 5N≥5那么与aaa接近的密码组合有535^353种,同理与bbb接近的密码组合也有535^353种;如果N<5N<5N<5,那么与aaa或bbb接近的密码组合只有N3N^3N3种。设函数single()single()single()返回与某一个密码接近的密码数量,那么分别与a,ba,ba,b接近的密码组合一共有single()∗2single()*2single()∗2种。

我们还需要除去既和aaa接近同时也和bbb接近的密码,因为这类密码被算了两次。接下来我们对aia_iai​与bib_ibi​的位置关系进行分析:

  • 当aia_iai​与bib_ibi​的距离为555时,在ai,bia_i,b_iai​,bi​之间无论取哪个数都无法做到和ai,bia_i,b_iai​,bi​的距离都小于等于222,因此重合的选择数量为000;
  • 当aia_iai​与bib_ibi​的距离为444时,只有选中间的点满足到ai,bia_i,b_iai​,bi​的距离都小于等于222,因此重合的选择数量为111;
  • 当aia_iai​与bib_ibi​的距离为333时,选ai,bia_i,b_iai​,bi​之间的两个点种的任意一个都满足要求,因此重合的选择数量为222;
  • 当aia_iai​与bib_ibi​的距离为222时,重合的选择数量为333;
  • 当aia_iai​与bib_ibi​的距离为111时,重合的选择数量为444;
  • 当aia_iai​与bib_ibi​的距离为000时,重合的选择数量为555。

因此,当aia_iai​与bib_ibi​的距离为disdisdis时,重合的选择数量为max(0,5−dis)max(0,5-dis)max(0,5−dis)。

当aia_iai​与bib_ibi​的距离小于等于111时,假设该距离表示圆上的劣弧ai,bia_i,b_iai​,bi​,那么我们会发现重合的点不仅可以选在劣弧上,也可以选在优弧上,那么会不会重复计算呢?

当N≤5N\le 5N≤5时,无论选择哪个点都满足到aia_iai​与bib_ibi​的距离小于等于222,因此重合的密码一共有N3N^3N3种。当N>5N>5N>5时,我们讨论以下两种情况:

  • ai,bia_i,b_iai​,bi​的距离为000,那么另一半弧长为N−dis>5N-dis>5N−dis>5,由之前的分析可知在这段弧中满足重合条件的点数量为000,因此不会重复计算;
  • ai,bia_i,b_iai​,bi​的距离为111,那么另一半弧长为N−dis≥5N-dis\ge 5N−dis≥5,同理在这段弧中满足重合条件的点数量也为000,同样不会重复计算。

所以aia_iai​与bib_ibi​之间最多只会有一段弧被计算,不会重复计算。


【O(n3)O(n^3)O(n3)代码】

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;const int N = 110;
int a[N], b[N];
int n, res;bool check(int x, int y, int z)
{int tmp[3] = { x, y, z };bool flag1 = true, flag2 = true;for (int i = 0; i < 3; i++){if (abs(tmp[i] - a[i]) > 2 && n - abs(tmp[i] - a[i]) > 2) flag1 = false;if (abs(tmp[i] - b[i]) > 2 && n - abs(tmp[i] - b[i]) > 2) flag2 = false;}if (flag1 || flag2) return true;return false;
}int main()
{cin >> n;for (int i = 0; i < 3; i++) cin >> a[i];for (int i = 0; i < 3; i++) cin >> b[i];for (int x = 1; x <= n; x++)for (int y = 1; y <= n; y++)for (int z = 1; z <= n; z++)if (check(x, y, z)) res++;cout << res << endl;return 0;
}

【O(1)O(1)O(1)代码】

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;const int N = 110;
int a[N], b[N];
int n;int single()
{int res = 1;for (int i = 0; i < 3; i++)res *= min(n, 5);return res;
}int repeat()
{if (n <= 5) return n * n * n;int res = 1;for (int i = 0; i < 3; i++){int dis = abs(a[i] - b[i]);res *= max(0, 5 - dis) + max(0, 5 - (n - dis));}return res;
}int main()
{cin >> n;for (int i = 0; i < 3; i++) cin >> a[i];for (int i = 0; i < 3; i++) cin >> b[i];cout << single() * 2 - repeat() << endl;return 0;
}

AcWing 1351. 密码锁(枚举,容斥原理)相关推荐

  1. 1351. 密码锁【难度: 一般 / 知识点: 枚举 容斥原理】

    https://www.acwing.com/problem/content/1353/ 暴力枚举: #include<bits/stdc++.h> using namespace std ...

  2. 【USACO training】Chapter 1 入门

    整理的算法模板合集: ACM模板 目录 Section 1.1 介绍 Section 1.2 提交解决方案,任务类型,特殊问题 1.2.1 AcWing 1339. 你的旅途由此开始(字符串模拟) 1 ...

  3. 算法——AcWing算法提高课中代码和题解

    文章目录 第一章 动态规划 (完成情况:64/68) 数字三角形模型 最长上升子序列模型 背包模型 状态机模型 状态压缩DP 区间DP 树形DP 数位DP 单调队列优化DP 斜率优化DP 第二章 搜索 ...

  4. 【初等数论】【转载】夜深人静写算法(五) - 初等数论

    [特殊声明:本文为转载文章] 本文转载地址--感谢文章博主 目录 一.数论基本概念 1.整除性 2.素数 a.素数与合数 b.素数判定 c.素数定理 d.素数筛选法 3.因数分解 a.算术基本定理 b ...

  5. AcWing 890. 能被整除的数(容斥原理)

    题目链接 https://www.acwing.com/problem/content/892/ 思路 我们可以直接通过除法来计算每一个质数的倍数有多少个,但是这样的话可能会出现重复计算的情况,例如6 ...

  6. 《算法竞赛进阶指南》打卡-基本算法-AcWing 95. 费解的开关:位运算、枚举、递推

    文章目录 题目解答 题目来源 题目解答 分析: 枚举第一行,指的是第一行哪些位置要切换状态!!!.第一行总共有5个数,组合数是32,即第一行哪些位置要切换总共有32种情况.这就是我们的枚举空间.比如, ...

  7. 《算法竞赛进阶指南》打卡-基本算法-AcWing 93. 递归实现组合型枚举:递归与递推、dfs、状态压缩

    文章目录 题目解答 题目链接 题目解答 分析: 此题和笔者另一篇博文很像,只不过是限定了个数.<算法竞赛进阶指南>打卡-基本算法-AcWing 92. 递归实现指数型枚举:递推与递归.二进 ...

  8. 《算法竞赛进阶指南》打卡-基本算法-AcWing 92. 递归实现指数型枚举:递推与递归、二进制状态压缩、dfs

    文章目录 题目解答 题目链接 题目解答 分析: 优化:用二进制状态压缩,也就是用二进制上的位来记录数有没有被用过. ac代码 #include<bits/stdc++.h> using n ...

  9. 容斥原理(二进制枚举)

    在计数时,必须注意无一重复,无一遗漏.为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计 ...

最新文章

  1. Hyperledger Grid:一个用于分布式供应链解决方案的框架
  2. set list词频排序java_Hadoop WordCount改进实现正确识别单词以及词频降序排序 | 学步园...
  3. SAP PM 初级系列10 - 维护通知单相关的配置
  4. 博客园里有多少人对企业信息化感兴趣
  5. 剑指offer 算法 (代码的完整性)
  6. 俄罗斯方块新增行算法:不拘一格编程序之二
  7. PicCompress一个精简的图片压缩工具
  8. sql倒序排列取第一条_从零学会SQL·三——汇总分析
  9. 【SQL】血缘解析 SQL parser 工具介绍
  10. python获取当前日期的前一天爆炸_python蒙特卡洛脚本模拟—挑战者号爆炸概率
  11. 原型模式(Prototype )
  12. QQ音乐爬虫之放弃的路
  13. July:海量数据处理
  14. 1.初识elasticsearch
  15. python基于flask_sockets实现WebSocket
  16. RealView MDK 使用
  17. vbs过程参数--byref和byval
  18. 【AE软件】视频添加字幕
  19. 使用git对word进行版本控制
  20. 操作系统精选习题——第二章

热门文章

  1. PLCSIM adv 3.0 不能启动 virtual ETH adapter
  2. Unreal UFUNCTION函数宏标记
  3. signature=bad8c09852a4072ccfb624d263bf7df8,河北专接本英语历年真题(附答案)
  4. Provide/inject 真的可以取代 Vuex 吗?
  5. 手把手教您搭建微信小程序商城?(二)
  6. RSA-PHP解密demo
  7. 【微信小程序控制硬件⑦ 进阶篇】动起来做一个微信小程序Mqtt协议控制智能硬件的框架,为心里全栈工程师梦想浇水。
  8. T039基于51单片机射频RFID卡考勤人数计数系统设计原理图PCB
  9. 666,太香了!Python 50 个正则表达式写法,建议收藏
  10. 郑州别墅智能家居案例——万发智能