《啊哈算法》第三章--枚举很暴力
从无到有学算法(看漫画学算法)
(๑•̀ㅂ•́)و✧ 爱要坦荡荡 - 萧潇 - 单曲 - 网易云音乐
一,坑爹的奥数
枚举算法又叫穷举算法,非常的暴力,它的基本思想是“有序地去尝试每一种可能”
题目1
□3 x 6528 = 3□ x 8256,在 □ 里填入相同数字使等式成立
#include<iostream>
using namespace std;
int main()
{for(int i = 1; i <= 9; ++i)if((i*10+3)*6528 == (30+i) * 8256)cout<<i<<endl;return 0;
}
4
题目2
□□□ + □□□ = □□□
将数字1 ~ 9分别填入 □ 种,每个数字只能使用一次使等式成立
比如173 + 286 = 459 与 286 + 173 = 459 为一种可能
思路
9个 □ 采用 9 个 for 循环遍历,用 a[i] 表示第 i 个格子地数字,通过book数组标记数字1 ~ 9是否出现过
如果满足每个数字只出现一次,且满足等式,ans++,注意最后输出ans / 2
同时,为避免book[i]累加,每次开始前都要归零
#include<iostream>
using namespace std;
int a[10], book[10];
int main()
{int i, ans = 0; //可能的情况for(a[1] = 1; a[1] <= 9; ++a[1])for(a[2] = 1; a[2] <= 9; ++a[2])for(a[3] = 1; a[3] <= 9; ++a[3])for(a[4] = 1; a[4] <= 9; ++a[4])for(a[5] = 1; a[5] <= 9; ++a[5])for(a[6] = 1; a[6] <= 9; ++a[6])for(a[7] = 1; a[7] <= 9; ++a[7])for(a[8] = 1; a[8] <= 9; ++a[8])for(a[9] = 1; a[9] <= 9; ++a[9]) { //9个格子,9个forfor(i = 1; i <= 9; ++i)book[i] = 0;//每次归零for(i = 1; i <= 9; ++i)book[a[i]] = 1; //标记是否出现int sum = 0; //统计不同数字个数for(i = 1; i<= 9; ++i)sum += book[i]; //这里不是book[a[i]]if(sum == 9 && a[1]*100+a[2]*10+a[3] + a[4]*100+a[5]*10+a[6] == a[7]*100+a[8]*10+a[9]) {ans++;cout<<a[1]<<a[2]<<a[3]<<"+"<<a[4]<<a[5]<<a[6]<<"="<<a[7]<<a[8]<<a[9]<<endl;}}cout<<ans / 2<<endl;return 0;
}
......(一共336行,所以是168种搭配)
738+216=954
739+125=864
745+218=963
745+236=981
746+235=981
748+215=963
752+184=936
754+182=936
762+183=945
763+182=945
782+154=936
782+163=945
783+162=945
784+152=936
168
二,炸弹人
还记得小霸王游戏机上的“炸弹人”吗,用放置炸弹的方法来消灭敌人
炸弹的爆炸方向沿上下左右四个方向
问在哪里放置炸弹可以消灭最多的敌人,已知两种墙,一种可以被炸掉
由于现在只有一枚炸弹,所以墙都用"#"表示(一枚炸弹可以炸掉这种墙,但也会被挡住)
敌人用"G"表示,空地用"."表示,只有空地才能放置炸弹
代码中的x, y表示第x行,第y列,且从第0行第0列开始计算
这里介绍一下走格子的表示方法:
向上 x--,向下 x++,向左 y--,向右 y++
统计每一个空地放置炸弹,可以消灭的总人数(上下左右四个方向敌人个数的和)
#include<iostream>
#include<cstdio> //printf()
using namespace std;
int main()
{char a[20][20];int m, n;cin>>m>>n; //m行,n列for(int i = 0; i < m; ++i)cin>>a[i]; //输入m行字符串int sum, i, j; //每个点消灭敌人个数int ans = 0, maxi = 0, maxj = 0;//两个for枚举地图中每个点for(i = 0; i < m; ++i)for(j = 0; j < n; ++j) {if(a[i][j] == '.') {//是空地sum = 0; //消灭敌人个数//向上int x = i, y = j;while(a[x][y] != '#') {//不是墙if(a[x][y] == 'G') //遇到敌人sum++; //消灭x--; //x--要和if并列}//向下x = i, y = j;while(a[x][y] != '#') {//不是墙if(a[x][y] == 'G')sum++;x++;}//向左x = i, y = j;while(a[x][y] != '#') {//不是墙if(a[x][y] == 'G')sum++;y--;}//向右x = i, y = j;while(a[x][y] != '#') {//不是墙if(a[x][y] == 'G')sum++;y++;}if(sum > ans) { //这个if要放在空地的if里ans = sum; //保留最大值maxi = i;maxj = j;}}}printf("将炸弹放在(%d, %d)处,最多可以消灭%d个敌人",maxi, maxj, ans);//i, j要声明在遍历之前,否则输出0,0return 0;
}
13 13
#############
#GG.GGG#GGG.#
###.#G#G#G#G#
#.......#..G#
#G#.###.#G#G#
#GG.GGG.#.GG#
#G#.#G#.#.###
##G...G.....#
#G#.#G###.#G#
#...G#GGG.GG#
#G#.#G#G#.#G#
#GG.GGG#G.GG#
#############
将炸弹放在(9, 9)处,最多可以消灭8个敌人
还有个问题!
如果将(6, 11)改为平地,小人默认站在(3, 3)这里,根据之前的算法
炸弹放在(1, 11)处,最多可以消灭11个敌人,但小人根本走不到(1, 11)处
13 13
#############
#GG.GGG#GGG.#
###.#G#G#G#G#
#.......#..G#
#G#.###.#G#G#
#GG.GGG.#.GG#
#G#.#G#.#.#.#
##G...G.....#
#G#.#G###.#G#
#...G#GGG.GG#
#G#.#G#G#.#G#
#GG.GGG#G.GG#
#############
将炸弹放在(1, 11)处,最多可以消灭11个敌人
正确答案应该是放在(7, 11)处,可以消灭10个敌人,怎么解决这个问题呢?
我会在《啊哈算法》第四章的博客解决这个问题
三,火柴棍等式(NOIP2008提高组)
小哼有 n(n <= 24) 根火柴棍,希望拼出形如 A + B = C 的等式,等式种的A,B,C均是用火柴棍拼出的整数(若该数非0,则最高位不为0),数字 1 ~ 9 的拼法如下图所示
要求:
1,+ 与 = 共需要4根火柴棍
2,如果 A != B,则 A + B = C 与 B + A = C 视为不同等式(A,B,C 都大于 0)
3,所有火柴棍都要用上
注意:
代码第18,19行,为什么遍历到1111呢,因为 n <= 24,除掉 = 和 + 那4跟,还剩20跟
0 ~ 9 中数字 1 需要的火柴棍最少,只需要2根,而20根火柴棍最多组成10个1,所以A,B,C任何一个数都不超过1111
#include<iostream>
using namespace std;
int num(int x) //写个判断火柴数的函数
{int a[10] = {6,2,5,5,4,5,6,3,7,6}; //单个数字对应的火柴数int sum = 0; //火柴数while(x / 10 != 0) {sum += a[x%10]; //敲重点x /= 10;}sum += a[x]; //此时x为个位数return sum;
}
int main()
{int n, c, all = 0;cin>>n; //总的火柴数for(int i = 0; i <= 1111; ++i)for(int j = 0; j <= 1111; ++j) {c = i + j; //"="右边的数if(num(i) + num(j) + num(c) == n - 4) {cout<<i<<"+"<<j<<"="<<c<<endl;all++;}}cout<<"可以拼出"<<all<<"种不同等式"<<endl;return 0;
}
18
0+4=4
0+11=11
1+10=11
2+2=4
2+7=9
4+0=4
7+2=9
10+1=11
11+0=11
可以拼出9种不同等式
四,数的全排列
这一小节只是为了下一章搜索(dfs等)的引入
123的全排列是123,132,213,231,312,321
1234的全排列是....
123的全排列可以用三重for循环嵌套
1234可以用四重for.....
但如果求123456789的全排列呢,,,
那如果输入n求1 ~ n的全排列呢?比如输入13,求12345678910111213的全排列....
欲知后事如何,且听下回分解(本来打算用随机数做下,感觉半小时写不出来就算了)
《啊哈算法》第三章--枚举很暴力相关推荐
- Java算法--第三章--排序(14)概述
Java算法–第三章–排序(14)概述 排序算法的总结: 一.基础排序-----算法评估等级:O(n²) 1.冒泡 谁大谁上,每一轮都把最大的顶到天花板效率太低O(n2)–掌握swap 2.选择排序, ...
- 啊哈算法——第三章:暴力枚举
第三章:暴力枚举 枚举的思想不必多说,此处仅引数中两例. 火柴棍等式 #include <iostream> using namespace std; const int maxn = 1 ...
- 斗地主AI算法——第三章の数据处理
上一章我们定义了基本的数据结构,相信大家看到手牌类里面那么多出牌序列时一定会比较愤慨... 其实一开始写的时候我也是觉得很脑残,不过后续开发证明了这样的结构还是可以的,因为只要我封装了一层数据转换,接 ...
- 终极算法——第三章:符号学派:休谟的归纳问题
本文为阅读总结个人认为书里概念性的.对本人有帮助的内容,仅供参考. 你是理性主义者还是经验主义者? 理性主义者认为,感官会欺骗人,而逻辑推理是通往知识的唯一可靠的道路.经验主义者认为所有推理都不可靠, ...
- C语言程序设计(理论课)第二章(理解)算法和第三章数据类型及其运算
第二章算法--程序的灵魂 算法+数据结构=程序 数据结构 对数据的描述.在程序中要指定用到哪些数据,以及这些数据的类型和数据的组织形式. 算法 对操作的描述.即要求计算机进行操作的步骤. 广义的 ...
- 啊哈算法第四章 万能的搜索
从这一章开始就真的步入对我而言全新的算法世界了(因为排序.枚举在上学期还是接触过的,而栈.队列在这学期我看的C++Primer和老师教的Java课里也有所涉及) 一.深度优先搜索(Depth Firs ...
- 计算机网络 第三章 数据链路层
有一说一,王道的计算机网络个人感觉不尽如意,数据链路层的内容安排实在是有些乱,里面并不是按照课本来的,而是穿插了很多其它章节的知识. 3.1 数据链路层的功能 数据链路层在物理层提供服务的基础上,向网 ...
- 北邮22信通:(2)第三章单链表
相信有了第二章顺序表的基础,小伙伴们学习第三章链表应该会轻松一点吧 目录 类模板下的单链表 1.1书上干净完整代码(无增改.适合自己动手实验) 1.2对书上代码的完善和对一些问题的验证和解释代码 1. ...
- 《啊哈算法》的Java现实 | 第三章:枚举!很暴力
<啊哈算法>的Java现实 | 第一章:排序. <啊哈算法>的Java现实 | 第二章:栈.队列.链表. <啊哈算法>的Java现实 | 第三章:枚举!很暴力. & ...
最新文章
- HDOJ - 4474 简单分析后,BFS
- 仅靠一种普通的泡沫橡胶,这台机器人解决了“爬楼梯”的难题
- Codeup-问题 B: 采药
- 奇小葩讲设备树(1/5)-- Linux设备树详解(一) 基础知识
- 服务器系统装软路由,服务器系统设置软路由
- 2017西安交大ACM小学期数论 [完全平方数]
- android 收获地址管理,android UiAutomator添加收货地址的用例
- 查看你某条sql是哪个用户执行的_django_debug_toolbar:查看访问某个页面执行sql的详细...
- boot空间不足 linux,linux——boot空间不足
- python单元测试示范卷_Python单元测试--Unittest
- 命名实体识别NER:LSTM-CRF模型
- [裴礼文数学分析中的典型问题与方法习题参考解答]5.1.23
- java tomcat热部署_intellij idea tomcat热部署配置教程
- mysql增删改查语法
- genymotion配置android模拟器
- 零极限:关于蓝色太阳水原理
- 一文搞懂 | Linux 同步管理(上)
- 仿QQ和飞秋并支持语音视频白板屏幕共享的即时聊天软件
- 蓝桥杯真题 - 费解的开关题解
- 广发卡分期可商户分期啦