第一题

美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。
他曾在1935~1936年应邀来中国清华大学讲学。 一次,他参加某个重要会议,年轻的脸孔引人注目。
于是有人询问他的年龄,他回答说:
“我年龄的立方是个4位数。我年龄的4次方是个6位数。这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。”
请你推算一下,他当时到底有多年轻。


解法:
  此题是固定无输入的填空题,则要贯彻实用性原则,不用考虑算法一定要按照题目中给出的逻辑来设计,而是要其问题的本质:我们的目的是得到Wiener的年龄,所以可以直接通过猜测试探的方法直接打印结果,观察得到答案。

public static int wienerSAge() {for (int i = 10; i < 30; i++) {int    three = i * i * i;String a     = String.valueOf(three);String b     = String.valueOf(three * i);if (a.length() == 4 && b.length() == 6) {StringBuilder sb = new StringBuilder(a);System.out.println(i);}}return 18;
}

第二题

本题目的要求是:请编写程序,由用户输入若干个罗马数字串,程序输出对应的十进制表示。
输入格式是:第一行是整数n,表示接下来有n个罗马数字(n<100)。
以后每行一个罗马数字。罗马数字大小不超过999。
要求程序输出n行,就是罗马数字对应的十进制数据。
例如,用户输入:
3
LXXX
XCIII
DCCII
则程序应该输出:
80
93
702


解法:
  常规来讲,在遇到字符转换这类题目的时候,纯粹想从输入直接转换到输出的算法在竞赛中是不常出现的——因为真要考虑的面面俱到的情况是非常困难的,并且代码编写的时间会非常久。这是非常不划算的。


(一)
  我们可以这样考虑,题目给出的输入范围是1-999,并且每位都不存在0,同时我们知道要直接将罗马数字转换成阿拉伯数字是很困难的,我们不妨试试将1-999范围内的阿拉伯数字转换成罗马数字,然后通过比较来得出每个输入的罗马数字对应的阿拉伯数字
  这样的算法会相当耗时,但我们在竞赛中的目的就是AC而已,不要太纠结于实用性,并且即使在工作过程中,开发速度也是很重要的,不要太过严谨而忽略了实用性。

public static List<Integer> transFormatRomeNumber(List<String> romeNums) {Map<Integer, String> map = new HashMap<Integer, String>() {{put(1, "I");put(5, "V");put(10, "X");put(50, "L");put(100, "C");put(500, "D");put(1000, "M");put(4, "IV");put(9, "IX");put(40, "XL");put(90, "XC");put(400, "CD");put(900, "CM");}};List<Integer> ret = new ArrayList<>();for (String romeNum : romeNums) {for (int i = 1; i <= 999; i++) {StringBuilder sb = new StringBuilder();int h = i / 100;int t = i % 100 / 10;int o = i % 10;if (h != 0) {if (h == 1) sb.append(map.get(100));if (h == 2) sb.append(map.get(100)).append(map.get(100));if (h == 3) sb.append(map.get(100)).append(map.get(100)).append(map.get(100));if (h == 4) sb.append(map.get(400));if (h == 5) sb.append(map.get(500));if (h == 6) sb.append(map.get(500)).append(map.get(100));if (h == 7) sb.append(map.get(500)).append(map.get(100)).append(map.get(100));if (h == 8) sb.append(map.get(500)).append(map.get(100)).append(map.get(100)).append(map.get(100));if (h == 9) sb.append(map.get(900));}if (t != 0) {if (t == 1) sb.append(map.get(10));if (t == 2) sb.append(map.get(10)).append(map.get(10));if (t == 3) sb.append(map.get(10)).append(map.get(10)).append(map.get(10));if (t == 4) sb.append(map.get(40));if (t == 5) sb.append(map.get(50));if (t == 6) sb.append(map.get(50)).append(map.get(10));if (t == 7) sb.append(map.get(50)).append(map.get(10)).append(map.get(10));if (t == 8) sb.append(map.get(50)).append(map.get(10)).append(map.get(10)).append(map.get(10));if (t == 9) sb.append(map.get(90));}if (o != 0) {if (o == 1) sb.append(map.get(1));if (o == 2) sb.append(map.get(1)).append(map.get(1));if (o == 3) sb.append(map.get(1)).append(map.get(1)).append(map.get(1));if (o == 4) sb.append(map.get(4));if (o == 5) sb.append(map.get(5));if (o == 6) sb.append(map.get(5)).append(map.get(1));if (o == 7) sb.append(map.get(5)).append(map.get(1)).append(map.get(1));if (o == 8) sb.append(map.get(5)).append(map.get(1)).append(map.get(1)).append(map.get(1));if (o == 9) sb.append(map.get(9));}if (sb.toString().equals(romeNum)) {ret.add(i);}}}return ret;
}

(二)
  如果使用上面的方法,在遇到规模巨大的输入时(比如上十万,百万个罗马数字),最坏将会执行输入规模*999次换算、比较操作,这是不切实际的,可以说上面的做法是很取巧的。
  这里说一下第二种解法,我们注意到在罗马数字中大多是低位在高位右边表示加,反过来表示减。同时,通过观察可以知道逆序的情况非常少,只有4、9、40、90、400、900,这样我们就可以通过“补偿”的思想——即将相同的部分做统一操作,将不同的部分再做另一次统一操作,来实现罗马数字的换算算法。

public static int romeNum(String s){int sum = 0;for(int i=0; i<s.length(); i++){char c = s.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;}// 补偿if(s.indexOf("IV")>=0) sum -= 2;if(s.indexOf("IX")>=0) sum -= 2;if(s.indexOf("XL")>=0) sum -= 20;if(s.indexOf("XC")>=0) sum -= 20;if(s.indexOf("CD")>=0) sum -= 200;if(s.indexOf("CM")>=0) sum -= 200;return sum;
}

第三题

小明最近在教邻居家的小朋友小学奥数,而最近正好讲述到了三阶幻方这个部分。
三阶幻方指的是将1~9不重复的填入一个3*3的矩阵当中,使得每一行、每一列和每一条对角线的和都是相同的。
三阶幻方又被称作九宫格,在小学奥数里有一句非常有名的口诀:
“二四为肩,六八为足,左三右七,戴九履一,五居其中”,
通过这样的一句口诀就能够非常完美的构造出一个九宫格来。
4 9 2
3 5 7
8 1 6
有意思的是,所有的三阶幻方,都可以通过这样一个九宫格进行若干镜像和旋转操作之后得到。
现在小明准备将一个三阶幻方(不一定是上图中的那个)中的一些数抹掉,交给邻居家的小朋友来进行还原
并且希望她能够判断出究竟是不是只有一个解。
而你呢,也被小明交付了同样的任务,但是不同的是,你需要写一个程序~
输入格式:
  输入仅包含单组测试数据。
  每组测试数据为一个3*3的矩阵,其中为0的部分表示被小明抹去的部分。
  对于100%的数据,满足给出的矩阵至少能还原出一组可行的三阶幻方。
输出格式:
  如果仅能还原出一组可行的三阶幻方,则将其输出,否则输出“Too Many”(不包含引号)。
样例输入
  0 7 2
  0 5 0
  0 3 0
样例输出
  6 7 2
  1 5 9
  8 3 4


解法:
  其实作为算法初心者的笔者在看到这道题的时候是有点懵的,甚至会去想比如一行一列如果全为零就肯定是Too Many啊…之类的想法。
  但其实这道题根本没有那么复杂,这就是经验不足导致的问题:
  我们往往是根据题目给我们的逻辑来思考问题。
  这样就没有一个问题转换的过程,在数学中很多问题的推导都是通过将一个复杂的问题简单化到一些已经证明正确的小问题上然后才得出结果。
  经过前三题的学习,我们也必须学会在拿到问题之后,不要急着下手,一定要好好思考之后再确定解题逻辑。
  好,让我们思考一下,三阶幻方的解法,究竟有多少种呢?
  。。。。。。
  其实只有8种。

/*
4 9 2
3 5 7
8 1 6
"492357816"8 3 4
1 5 9
6 7 2
"834159672"0 7 2
0 5 0
0 3 0*/
public class A{static boolean test(String std, String s){for(int i=0; i<std.length(); i++){if(std.charAt(i) == s.charAt(i)) continue;if(s.charAt(i)=='0') continue;return false;}return true;}
public static void main(String[] args){String s = "072050030";String[] ss = {"492357816","834159672","618753294","276951438","294753618","438951276","816357492","672159834"};int onlyWay = 0;String way = null;for(int i=0; i<ss.length; i++){if(test(ss[i],s)){onlyWay++;way = ss[i];                }}if(onlyWay == 1){System.out.println(way.substring(0,3));System.out.println(way.substring(3,6));System.out.println(way.substring(6,9));}else{System.out.println("Too Many");}}
}

第四题

魔方可以对它的6个面自由旋转。
我们来操作一个2阶魔方(如图1所示):
为了描述方便,我们为它建立了坐标系。
各个面的初始状态如下:
x轴正向:绿
x轴反向:蓝
y轴正向:红
y轴反向:橙
z轴正向:白
z轴反向:黄
假设我们规定,只能对该魔方进行3种操作。分别标记为:
x表示在x轴正向做顺时针旋转
y表示在y轴正向做顺时针旋转
z表示在z轴正向做顺时针旋转
xyz则表示顺序执行x,y,z 3个操作
题目的要求是:
用户从键盘输入一个串,表示操作序列。
程序输出:距离我们最近的那个小方块的3个面的颜色。
顺序是:x面,y面,z面。
例如:在初始状态,应该输出:
绿红白
初始状态下,如果用户输入:
x
则应该输出:
绿白橙
初始状态下,如果用户输入:
zyx
则应该输出:
红白绿


解法:
  这道题就是将模仿的六个面展开,并写出每次x、y、z操作对应的面的转换,也就是没什么取巧的地方,直接对数据源进行操作,然后得出结果。
  不过在这里我的做法相对较死脑筋一些,而老师给出的做法是对每个面进行了编号,这样三种操作可以直接写死,可以大大减少编码时间。


(一)

/*** 魔方旋转** @param moves* @return*/
public static String pocketCubeRotate(String moves) {/*Scanner scanner = new Scanner(new BufferedInputStream(System.in));String moves = scanner.next();System.out.println(pocketCubeRotate(moves));*/String[][] cube = {{"", "", "w", "w", "", "", "", ""},{"", "", "w", "w", "", "", "", ""},{"o", "o", "g", "g", "r", "r", "b", "b"},{"o", "o", "g", "g", "r", "r", "b", "b"},{"", "", "y", "y", "", "", "", ""},{"", "", "y", "y", "", "", "", ""},};char[] movings = moves.toCharArray();for (char c : movings) {switch (c) {case 'x':String tX1 = cube[1][2];String tX2 = cube[1][3];cube[1][2] = cube[3][1];cube[1][3] = cube[2][1];cube[3][1] = cube[4][3];cube[2][1] = cube[4][2];cube[4][3] = cube[2][4];cube[4][2] = cube[3][4];cube[2][4] = tX1;cube[3][4] = tX2;String tX3 = cube[2][2];cube[2][2] = cube[3][2];cube[3][2] = cube[3][3];cube[3][3] = cube[2][3];cube[2][3] = tX3;break;case 'y':String tY1 = cube[0][3];String tY2 = cube[1][3];cube[0][3] = cube[2][3];cube[1][3] = cube[3][3];cube[2][3] = cube[4][3];cube[3][3] = cube[5][3];cube[4][3] = cube[3][6];cube[5][3] = cube[2][6];cube[3][6] = tY1;cube[2][6] = tY2;String tY3 = cube[2][4];cube[2][4] = cube[3][4];cube[3][4] = cube[3][5];cube[3][5] = cube[2][5];cube[2][5] = tY3;break;case 'z':String tZ1 = cube[2][0];String tZ2 = cube[2][1];cube[2][0] = cube[2][2];cube[2][1] = cube[2][3];cube[2][2] = cube[2][4];cube[2][3] = cube[2][5];cube[2][4] = cube[2][6];cube[2][5] = cube[2][7];cube[2][6] = tZ1;cube[2][7] = tZ2;String tZ3 = cube[0][2];cube[0][2] = cube[1][2];cube[1][2] = cube[1][3];cube[1][3] = cube[0][3];cube[0][3] = tZ3;break;}}Map<String, String> map = new HashMap<String, String>() {{put("w", "白");put("o", "橙");put("g", "绿");put("r", "红");put("b", "蓝");put("y", "黄");}};String x = map.get(cube[2][3]);String y = map.get(cube[2][4]);String z = map.get(cube[1][3]);return x + y + z;
}

(二)

/*二阶魔方的各个面给一个唯一编号:16 1719 18------- 12 13 |  0  1 |  4  5 |  8  915 14 |  3  2 |  7  6 | 11 10-------20 2123 22上左前右后下x操作:(0,1,2,3)  (4,21,14,19)  (7,20,13,18)
y操作:(4,5,6,7)  (1,17,11,21)  (2,18,8,22)
z操作:(16,17,18,19) (0,12,8,4)  (1,13,9,5)
*/public class A {static int[][] transx = {{0, 1, 2, 3}, {4, 21, 14, 19}, {7, 20, 13, 18}};static int[][] transy = {{4, 5, 6, 7}, {1, 17, 11, 21}, {2, 18, 8, 22}};static int[][] transz = {{16, 17, 18, 19}, {0, 12, 8, 4}, {1, 13, 9, 5}};static char[] op(char[] a, int[][] trans) {char[] b = java.util.Arrays.copyOf(a, a.length);for (int i = 0; i < trans.length; i++) {b[trans[i][1]] = a[trans[i][0]];b[trans[i][2]] = a[trans[i][1]];b[trans[i][3]] = a[trans[i][2]];b[trans[i][0]] = a[trans[i][3]];}return b;}static char[] op(char[] a, String s) {char[] b = java.util.Arrays.copyOf(a, a.length);for (int i = 0; i < s.length(); i++) {if (s.charAt(i) == 'x') b = op(b, transx);if (s.charAt(i) == 'y') b = op(b, transy);if (s.charAt(i) == 'z') b = op(b, transz);}return b;}public static void main(String[] args) {char[] init = {'绿', '绿', '绿', '绿','红', '红', '红', '红','蓝', '蓝', '蓝', '蓝','橙', '橙', '橙', '橙','白', '白', '白', '白','黄', '黄', '黄', '黄',};char[] b = op(init, "xyxyzzxyxyzz");System.out.println("" + b[1] + b[4] + b[18]);}
}

第五题

当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?
其实可以不必这么担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过Luhn算法来验证通过。
该校验的过程:
1、从卡号最后一位数字开始,逆向将奇数位(1、3、5等等)相加。
2、从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,则将其减去9),再求和。
3、将奇数位总和加上偶数位总和,结果应该可以被10整除。
例如,卡号是:5432123456788881
则,奇数位和=35
偶数位乘以2(有些要减去9)的结果:1 6 2 6 1 5 7 7,求和=35。
最后35+35=70可以被10整除,认定校验通过。
请编写一个程序,从键盘输入卡号,然后判断是否校验通过。通过显示:“成功”,否则显示“失败”。
比如,用户输入:356827027232780
程序输出:成功


解法:
  Simple,不过注意初始位是0,奇数位判断条件应该是i%2==1,而不是0。

public class A {// s: 待验证的卡号static boolean f(String s) {int sum = 0;for (int i = 0; i < s.length(); i++) {int x = s.charAt(s.length() - i - 1) - '0';if (i % 2 == 1) {x = x * 2;if (x >= 10) x -= 9;}sum += x;}return sum % 10 == 0;}public static void main(String[] args) {System.out.println(f("356827027232780"));System.out.println(f("356406010024817"));System.out.println(f("358973017867744"));System.out.println(f("356827027232781"));System.out.println(f("306406010024817"));System.out.println(f("358973017867754"));}
}

蓝桥杯赛前冲刺补习第一课——《暴力与枚举》相关推荐

  1. 蓝桥杯赛前冲刺补习第四课——《数学知识的应用》

    第一题 地产大亨Q先生临终的遗愿是:拿出100万元给X社区的居民抽奖,以稍慰藉心中愧疚. 麻烦的是,他有个很奇怪的要求: 1.100万元必须被正好分成若干份(不能剩余). 每份必须是7的若干次方元. ...

  2. (蓝桥杯第一课)暴力破解与实用性优先

    杂谈--蓝桥杯该如何应对 打好基础最重要 90%是暴力破解,是其他高级算法的i 出 注重解决问题的能力 一.年龄谜题 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学. 他曾在1935~1 ...

  3. 蓝桥杯赛前真题 Python组 Day 4

    试题 算法训练 共线 资源限制 内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s 问题描述 给定2维平面上n个整点的坐标,一条直线最多 ...

  4. 第十三届蓝桥杯赛前的一点总结

    比赛最主要的实现功能,需要关注各个部分之间的逻辑! 赛前的一点总结 LED 数码管 独立按键 正常处理按键 长按键功能--规定秒数 长按键功能--不规定秒数 矩阵按键 4 * 4 矩阵按键 2 * 2 ...

  5. python编程入门第一课_python入门前的第一课 python怎样入门

    人工智能时代的到来,很多文章说这么一句:"不会python,就不要说自己是程序员",这说的有点夸张了,但确实觉得目前python这个语言值得学习,而且会python是高薪程序员的必 ...

  6. 第一课:暴力破解与实用性优先

    暴力是一种解决非常多问题的常用方法,解决问题之前应当先考虑是否课暴力,并非所有题都可暴力,但是暴力是一个很好的思路. 第一题:年龄谜题 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学. ...

  7. 【蓝桥杯刷题冲刺辅导】掌握递归·DFS解题套路,这一文足以?

    大家好,我是安然无虞. 目录 一.刷题前和铁汁们唠一唠 1.刷题前须知 2.刷题时套路 <1>套路 <2>背下列常用数 ​ <3>投机取巧:根据数据范围确定算法 ​ ...

  8. 蓝桥杯C++ AB组辅导课

    整理的算法模板合集: ACM模板 今天在AcWing闲逛白嫖到了yxc老师的蓝桥杯C++ AB组辅导课的题单,正好快要蓝桥杯了,我准备每天花半个小时刷5道这个题单里的水题,练一练,不然到时候我各种花里 ...

  9. 写给程序员的管理入门课程 -《格鲁夫给经理人的第一课》

    写给程序员的管理入门课程 -<格鲁夫给经理人的第一课> 序 格鲁夫给经理人的第一课 <格鲁夫给经理人的第一课> 最早出版于 2007 年,书原名为<High Output ...

最新文章

  1. 程序员你为什么这么累【续】:编码习惯之工具类规范
  2. golang中的sjson
  3. Golang类型转化方法汇总
  4. 实现省市二级联动效果
  5. HOW-TO:带有Spring MVC的Tomcat中的自定义错误页面
  6. 云原生之上,亚马逊云科技发布多项容器与Serverless服务,持续发力现代化应用
  7. linux修改密码的几种方法
  8. mysql怎么约束_MySQL 约束详解
  9. 70 行 Python 代码写春联,支持行书隶书楷书!
  10. 三十分钟理解:线性插值,双线性插值Bilinear Interpolation算法
  11. 毫米波雷达产业链全景
  12. 10x 程序员工作法 - 划重点 | “自动化”主题的重点内容回顾汇总
  13. funcode之c++版弹弹堂(第一个设计实验)
  14. 虚拟机学习(一)如何在虚拟机内安装系统
  15. 软件著作权保护的内容
  16. dreamweaver半角空格_Dreamweaver初学者小技巧应用系列--1.快速插入空格
  17. 基于移动最小二乘(MLS)的图像扭曲刚性变形python实现
  18. 软考信息系统项目管理师质量管理论文范例
  19. PMBOK第7版——「8大绩效域」解析
  20. Centos7 下 MySQL8.0 的安装

热门文章

  1. c语言二维vector大小,vector作为二维数组
  2. 穿透Windows防火墙唤醒后门
  3. 如何找到在东湾三谷一个好的汽车车身修理店
  4. maven plugin execution的用法
  5. 软件下载站点提交的一点经验.
  6. 虚拟机VMware Workstation 16 Pro安装步骤心得分享
  7. linux redhat 版本查看,查看RedHat linux版本的三种方法
  8. 贺岁杯围棋争霸赛打响 系列赛事启幕潘晓婷等将亮相
  9. 你一定不知道:冬至吃饺子是为了纪念谁?
  10. 中欧校友社区测试第一阶段之总结