1、暴力破解与实用性原则
2018-03-08 21:41
399 查看
暴力破解与实用性原则:
1)暴力破解的第一原则:实用性。2)枚举法。
3)逆向解法。
真题一 年龄谜题
美国数学家维纳(N.Wiener)智力早熟,11 岁就上了大学。 他曾在 1935-1936 年应邀来中国清华大学讲学。 一次,他参加某个重要会议,年轻的脸孔引人注目。 于是有人询问他的年龄,他回答说:“我年龄的立方是个 4 位数。我年龄的 4 次方是个6 位数。这 10 个数字正好包含了从 0 到 9 这 10 个数字,每个都恰好出现 1 次。”请你推算一下,他当时到底有多年轻。解题思路:
假设年龄是在1-50岁之间,暴力破解便是将1-50全部算出再筛选。1)计算1-50的立方以及4次方,剔除掉立方不是4位数的以及4次方不是6位数的结果。
很明显,在这里就已经可以看出答案是18岁。暴力破解原则就是要实用、高效、快速。
2)将年龄的立方以及4次方串起来,判断这10个数字是否正好包含了从0到9这10个数字,每个都恰好出现1次。
思路:判断0-9是否都出现在串中。
完整代码:
public class Main{ public static void main(String[] args){ for (int i=1; i<50; i++) { int a = i*i*i; int b = a * i; if((a+"").length() != 4 || (b+"").length() != 6) //判断年龄的立方是否4位数以及4次方是否6位数 continue; String s = "" + a + b; System.out.println(i + ": " + s + " " + isAnswer(s)); } } //判断是否是答案 public static boolean isAnswer(String s){ for (int i=0; i<10; i++) { if(s.indexOf(i+"") == -1) //0-9只要有一个不包含在s串中,直接返回false return false; } return true; } }
结果:
真题二:古罗马数字(枚举法)
古罗马帝国开创了辉煌的人类文明,但他们的数字表示法的确有些繁琐,尤其在示大数的时候,现在看起来简直不能忍受,所以在现代很少使用了。 之所以这样,不是因为发明表示法的人的智力的问题,而是因为一个宗教的原因,当时的宗教禁止在数字中出现 0 的概念! 罗马数字的表示主要依赖以下几个基本符号:I --> 1
V --> 5
X --> 10
L --> 50
C --> 100
D --> 500
M --> 1000
这里,我们只介绍一下 1000 以内的数字的表示法。
单个符号重复多少次,就表示多少倍。最多重复 3 次。
比如: CCC 表示 300 XX 表示 20,但 150 并不用 LLL 表示,这个规则仅适用于 I X C M。
如果相邻级别的大单位在右,小单位在左,表示大单位中扣除小单位。
比如: IX 表示 9 ,IV 表示 4 ,XL 表示 40 , 49 = XLIX
更多的示例参见下表,你找到规律了吗?
I = 1
II = 2
III = 3
IV = 4
V = 5
VI = 6
VII = 7
VIII = 8
IX = 9
X = 10
XI = 11
XII = 12
XIII = 13
XIV = 14
XV = 15
XVI = 16
XVII = 17
XVIII = 18
XIX = 19
XX = 20
XXI = 21
XXII = 22
XXIX = 29
XXX = 30
XXXIV = 34
XXXV = 35
XXXIX = 39
XL = 40
L = 50
LI = 51
LV = 55
LX = 60
LXV = 65
LXXX = 80
XC = 90
XCIII = 93
XCV = 95
XCVIII = 98
XCIX = 99
C = 100
CC = 200
CCC = 300
CD = 400
D = 500
DC = 600
DCC = 700
DCCC = 800
CM = 900
CMXCIX = 999
本题目的要求是:请编写程序,由用户输入若干个罗马数字串,程序输出对应的十进制表示。
输入格式是:第一行是整数 n,表示接下来有 n 个罗马数字(n<100)。 以后每行一个罗马数字。罗马数字大 小 不 超 过 999。 要求程序输出 n 行,就是罗马数字对应的十进制数据。
例如,用户输入:
3
LXXX
XCIII
DCCII
则程序应该输出:
80
93
702
解题思路:
1、遍历罗马数字字符串的每一个字符,将每个字符所对应的十进制数相加起来。2、因为存在着小单位在大单位左边这种情况,而且还不是所有的小单位放到大单位左边都成立。所以单单第一步是不够的,然而总结规律,这种特殊情况却少之又少:
IV:4 IX:9
XL:40 XC:90
CD:400 CM:900
因此,接下来就是直接枚举出这6种情况,对上述第一步所得出的sum进行补偿即可。
完整代码:
import java.util.Scanner; public class Main{ public static void main(String[] args){ String[] romeNums = new String ; Scanner s = new Scanner(System.in); int n = s.nextInt(); for(int i=0; i<n; i++){ romeNums[i] = s.next(); } for(int i=0; i<n; i++){ System.out.println(romeNumToDec(romeNums[i])); } } public static int romeNumToDec(String romeNum){ int sum = 0; for (int i=0; i<romeNum.length(); i++) { char c = romeNum.charAt(i); if(c == 'I') sum += 1; if(c == 'V') sum += 5; if(c == 'X') sum += 10; if(c == 'L') sum += 50; if(c == 'C') sum += 100; if(c == 'D') sum += 500; if(c == 'M') sum += 1000; } //对sum进行补偿 if(romeNum.indexOf("IV") != -1) sum -= 2; if(romeNum.indexOf("IX") != -1) sum -= 2; if(romeNum.indexOf("XL") != -1) sum -= 20; if(romeNum.indexOf("XC") != -1) sum -= 20; if(romeNum.indexOf("CD") != -1) sum -= 200; if(romeNum.indexOf("CM") != -1) sum -= 200; return sum; } }
结果:
问题:如何保证输入的罗马数字是正确的呢?
解决:可以采用逆向解法。
1)将罗马数字转为十进制数字;
2)设计一个方法,将所得到的十进制反而再转化为罗马数字;
3)将转化来的罗马数字与之前的比较看是否一致。
相关文章推荐
- 暴力破解与实用性优先(年龄谜题、九宫幻方)
- 暴力破解与实用性优先(罗马数字)
- (蓝桥杯第一课)暴力破解与实用性优先
- 蓝桥杯算法特训 | C++ | 暴力破解与实用性优先
- 一 . 暴力破解与实用性优先
- 永夜防暴力破解脚本
- Centos6.4 安装fail2ban防暴力破解
- ssh暴力破解防护软件
- Wifi密码破解之一:通过字典(暴力)破解WIFI密码
- DVWA 之暴力破解攻击(Brute Force)
- Linux下暴力破解工具Hydra详解
- Wordpress网站遭遇大规模暴力破解攻击之我也躺枪
- 路由器密码忘记 五步暴力破解
- 暴力破解--利用计算机执行速度
- [小技巧]mac本地暴力破解wifi密码
- BackTrack5 学习笔记8 密码暴力破解工具
- 代码原则,破解相关
- (原创)暴力破解西电校园网密码
- 关于csrss.exe和winlogon.exe进程多、占用CPU高的解决办法,有人在暴力破解