趣味算式
匪警请拨110,即使手机欠费也可拨通!
为了保障社会秩序,保护人民群众生命财产安全,警察叔叔需要与罪犯斗智斗勇,因而需要
经常性地进行体力训练和智力训练!
某批警察叔叔正在进行智力训练:
1 2 3 4 5 6 7 8 9 = 110;
请看上边的算式,为了使等式成立,需要在数字间填入加号或者减号(可以不填,但不能
填入其它符号)。之间没有填入符号的数字组合成一个数,例如:12+34+56+7-8+9 就是一种合格
的填法;123+4+5+67-89 是另一个可能的答案。
请你利用计算机的优势,帮助警察叔叔快速找到所有答案。
* 程序输出:
每个答案占一行。形如:
12+34+56+7-8+9
123+4+5+67-89
......
已知的两个答案可以输出,但不计分。
各个答案的前后顺序不重要。
注意:
请仔细调试!您的程序只有能运行出正确结果的时候才有机会得分!
下面附上最简单,但是效率非常差的一种解法,如果没有任何限定,此方法可行
效率耗费在调用js脚本函数上,所以我们后面给出,非js方法
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/**
* @createDate:2019年3月11日 下午10:25:11
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:趣味算式.java @describe:
*/
public class 趣味算式JavaScript {
static ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
static String d;
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "1";
long startTime = System.currentTimeMillis();
fun(str, 2);
long endTime = System.currentTimeMillis();
System.out.println("运行时间:" + (endTime - startTime) + "ms");
}
public static void fun(String str, int i) {
if (i == 10) {
try {
String d = se.eval(str).toString();
if (d.equals("110"))
System.out.println(str);
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
fun(str + "-" + String.valueOf(i), i + 1);
fun(str + "+" + String.valueOf(i), i + 1);
fun(str + "" + String.valueOf(i), i + 1);
}
}
}
下面附上效率相对较高的解法
import java.util.Stack;
/**
* @createDate:2019年3月12日 上午11:09:26
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:趣味算式.java @describe:
*/
public class 趣味算式 {
static Stack<Character> sta = new Stack<Character>();
static Stack<Integer> sums = new Stack<Integer>();
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "1";
long startTime = System.currentTimeMillis();
fun(str, 2);
long endTime = System.currentTimeMillis();
System.out.println("运行时间:" + (endTime - startTime) + "ms");
}
public static void fun(String str, int i) {
if (i == 10) {
if (GetStr(str) == 110) {
System.out.println(str);
}
} else {
fun(str + "-" + String.valueOf(i), i + 1);
fun(str + "+" + String.valueOf(i), i + 1);
fun(str + "" + String.valueOf(i), i + 1);
}
}
public static int GetStr(String str) {
int sum, t = 1, top, temp = 0, cnt = 0, b;
char a;
for (int i = str.length() - 1; i >= 0; i--) {
// 补充算式算法
if (str.charAt(i) == '+' || str.charAt(i) == '-') {
sta.push(str.charAt(i));
continue;
} else {
temp += t * (str.charAt(i) - '0');
t *= 10;
}
if (i == 0 || str.charAt(i - 1) == '+' || str.charAt(i - 1) == '-') {
sums.push(temp);
t = 1;
temp = 0;
}
}
cnt = sta.size();
for (int i = 0; i < cnt; i++) {
a = sta.pop();
if (a == '+') {
top = sums.pop() + sums.pop();
sums.push(top);
} else if (a == '-') {
top = sums.pop() - sums.pop();
sums.push(top);
}
}
int count = sums.pop();
sta.clear();
sums.clear();
return count;
}
}
总结:第二种方法使用了,波兰表达式的思想,堆栈计算
密码发生器
在对银行账户等重要权限设置密码的时候,我们常常遇到这样的烦恼:如果为了好记用生日吧,
容易被破解,不安全;如果设置不好记的密码,又担心自己也会忘记;如果写在纸上,担心纸张被
别人发现或弄丢了...
这个程序的任务就是把一串拼音字母转换为6位数字(密码)。我们可以使用任何好记的拼音
串(比如名字,王喜明,就写:wangximing)作为输入,程序输出6位数字。
变换的过程如下:
第一步. 把字符串6个一组折叠起来,比如wangximing则变为:
wangxi
ming
第二步. 把所有垂直在同一个位置的字符的ascii码值相加,得出6个数字,如上面的例子,
则得出:
228 202 220 206 120 105
第三步. 再把每个数字“缩位”处理:就是把每个位的数字相加,得出的数字如果不是一位
数字,就再缩位,直到变成一位数字为止。例如: 228 => 2+2+8=12 => 1+2=3
上面的数字缩位后变为:344836, 这就是程序最终的输出结果!
要求程序从标准输入接收数据,在标准输出上输出结果。
输入格式为:第一行是一个整数n(<100),表示下边有多少输入行,接下来是n行字符串,
就是等待变换的字符串。
输出格式为:n行变换后的6位密码。
* 输入描述:
例如,输入:
5
zhangfeng
wangximing
jiujingfazi
woaibeijingtiananmen
haohaoxuexi
* 程序输出:
772243
344836
297332
716652
875843
import java.util.Scanner;
/**
* @createDate:2019年3月12日 下午7:11:42
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:密码发生器.java @describe:
*/
public class 密码发生器 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String str[] = new String[n];
for (int i = 0; i < n; i++) {
str[i] = sc.next();
}
fun(str, n);
}
public static void fun(String str[], int n) {
int arr[][] = new int[n][6];
for (int i = 0; i < n; i++) {
for (int j = 0; j < str[i].length(); j++) {
arr[i][j % 6] += str[i].charAt(j);
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < 6; j++) {
arr[i][j] = funnum(arr[i][j]);
}
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j]);
}
System.out.println();
}
}
public static int funnum(int n) {
if (n < 10)
return n;
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
return funnum(sum);
}
}
手机尾号
30年的改革开放,给中国带来了翻天覆地的变化。2011全年中国手机产量约为11.72亿部。手机已经成为百姓的基本日用品!
给手机选个好听又好记的号码可能是许多人的心愿。但号源有限,只能辅以有偿选号的方法了。
这个程序的目的就是:根据给定的手机尾号(4位),按照一定的规则来打分。其规则如下:
1. 如果出现连号,不管升序还是降序,都加5分。例如:5678,4321都满足加分标准。
2. 前三个数字相同,或后三个数字相同,都加3分。例如:4888,6665,7777都满足加分的标准。注意:7777因为满足这条标准两次,所以这条规则给它加了6分。
3. 符合AABB或者ABAB模式的加1分。例如:2255,3939,7777都符合这个模式,所以都被加分。注意:7777因为满足这条标准两次,所以这条标准给它加了2分。
4. 含有:6,8,9中任何一个数字,每出现一次加1分。例如4326,6875,9918都符合加分标准。其中,6875被加2分;9918被加3分。
尾号最终得分就是每条标准的加分总和!
要求程序从标准输入接收数据,在标准输出上输出结果。
输入格式为:第一行是一个整数n(<100),表示下边有多少输入行,接下来是n行4位一组的数据,就是等待计算加分的手机尾号。
输出格式为:n行整数。
* 输入描述:
例如,输入:
14
3045
0211
2345
6543
7777
8888
7878
7788
6688
2424
2244
9918
6789
8866
* 程序输出:
0
0
5
6
8
12
3
3
5
1
1
3
8
5
import java.util.Scanner;
/**
* @createDate:2019年3月12日 下午7:38:27
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:手机尾号.java @describe:
*/
public class 手机尾号 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int arr[] = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
fun(arr, n);
}
public static void fun(int arr[], int n) {
int ret[] = new int[n];
int a, b, c, d, sum;
for (int i = 0; i < n; i++) {
sum = 0;
a = arr[i] / 1000;
b = arr[i] / 100 % 10;
c = arr[i] / 10 % 10;
d = arr[i] % 10;
if (a == b - 1 && a == c - 2 && a == d - 3 || a == b + 1 && a == c + 2 && a == d + 3) {
sum += 5;
}
if (b == c && b == d) {
sum += 3;
}
if (a == b && a == c) {
sum += 3;
}
if (a == b && c == d) {
sum += 1;
}
if (a == c && b == d) {
sum += 1;
}
if (a == 6 || a == 8 || a == 9) {
sum += 1;
}
if (b == 6 || b == 8 || b == 9) {
sum += 1;
}
if (c == 6 || c == 8 || c == 9) {
sum += 1;
}
if (d == 6 || d == 8 || d == 9) {
sum += 1;
}
ret[i] = sum;
}
for (int i = 0; i < ret.length; i++) {
System.out.println(ret[i]);
}
}
}
括号问题
下面的代码用于判断一个串中的括号是否匹配
所谓匹配是指不同类型的括号必须左右呼应,可以相互包含,但不能交叉
例如:
..(..[..]..).. 是允许的
..(...[...)....].... 是禁止的
对于 main 方法中的测试用例,应该输出:
false
true
false
false
import java.util.Stack;
/**
* @createDate:2019年3月12日 下午7:58:15
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:括号问题.java @describe:
*/
public class 括号问题 {
public static boolean isGoodBracket(String s) {
Stack<Character> a = new Stack<Character>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(')
a.push(')');
if (c == '[')
a.push(']');
if (c == '{')
a.push('}');
if (c == ')' || c == ']' || c == '}') {
if (a.empty())
return false; // 填空
if (a.pop() != c)
return false;
}
}
if (!a.empty())
return false; // 填空
return true;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(isGoodBracket("...(..[.)..].{.(..).}..."));
System.out.println(isGoodBracket("...(..[...].(.).){.(..).}..."));
System.out.println(isGoodBracket(".....[...].(.).){.(..).}..."));
System.out.println(isGoodBracket("...(..[...].(.).){.(..)...."));
}
}
扑克牌移动
下面代码模拟了一套扑克牌(初始排序A~K,共13张)的操作过程。
操作过程是:
手里拿着这套扑克牌,从前面拿一张放在后面,再从前面拿一张放桌子上,再从前面拿一张
放在后面,....
如此循环操作,直到剩下最后一张牌也放在桌子上。
下面代码的目的就是为了求出最后桌上的牌的顺序。
初始的排列如果是A,2,3...K,则最后桌上的顺序为:
[2, 4, 6, 8, 10, Q, A, 5, 9, K, 7, 3, J]
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
/**
* @createDate:2019年3月12日 下午8:20:15
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:扑克牌移动.java @describe:
*/
public class 扑克牌移动 {
public static List moveCard(List src) {
if (src == null)
return null;
List dst = new Vector();
for (;;) {
// 直到dst桌面排满
if (dst.size() == 13)
break; // 填空
// remove(0)的返回值是A,然后Src.add()相当于把A移到了末尾(牌底)
src.add(src.remove(0));
remove(0)的返回值是2,然后dst.add()相当于把2放到了桌面,从牌堆移除添加到dst
dst.add(src.remove(0)); // 填空
}
return dst;
}
public static void main(String[] args) {
List a = new Vector();
a.addAll(Arrays.asList("A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"));
System.out.println(moveCard(a));
}
}
第一个数字
以下的静态方法实现了:把串s中第一个出现的数字的值返回。
如果找不到数字,返回-1
例如:
s = "abc24us43" 则返回2
s = "82445adb5" 则返回8
s = "ab" 则返回-1
public static int getFirstNum(String s)
{
if(s==null || s.length()==0) return -1;
char c = s.charAt(0);
if(c>='0' && c<='9') return _____________; //填空
return getFirstNum(______________); //填空
}
/**
* @createDate:2019年3月12日 下午9:44:58
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:第一个数.java @describe:
*/
public class 第一个数 {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(getFirstNum("abc24us43"));
System.out.println(getFirstNum("82445adb5"));
System.out.println(getFirstNum("ab"));
}
static int getFirstNum(String s) {
if (s == null || s.length() == 0)
return -1;
char c = s.charAt(0);
if (c >= '0' && c <= '9')
return c - '0'; // 填空
return getFirstNum(s.substring(1)); // 填空
}
}
比酒量
有一群海盗(不多于20人),在船上比拼酒量。过程如下:打开一瓶酒,所有在场的
人平分喝下,有几个人倒下了。再打开一瓶酒平分,又有倒下的,再次重复...... 直到
开了第4瓶酒,坐着的已经所剩无几,海盗船长也在其中。当第4瓶酒平分喝下后,大家
都倒下了。
等船长醒来,发现海盗船搁浅了。他在航海日志中写到:“......昨天,我正好喝
了一瓶.......奉劝大家,开船不喝酒,喝酒别开船......”
请你根据这些信息,推断开始有多少人,每一轮喝下来还剩多少人。
如果有多个可能的答案,请列出所有答案,每个答案占一行。
* 程序输出: 格式是:人数,人数,... 例如,有一种可能是:20,5,4,2,0
/**
* @createDate:2019年3月12日 下午9:48:26
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:比酒量.java @describe:
*/
public class 比酒量 {
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 20; i >= 1; i--) {
for (int j = i - 1; j >= 1; j--) {
for (int k = j - 1; k >= 1; k--) {
for (int t = k - 1; t >= 1; t--) {
if ((1.0 / i + 1.0 / j + 1.0 / k + 1.0 / t) == 1)
System.out.printf("%d\t%d\t%d\t%d\t%d\n", i, j, k, t, 0);
}
}
}
}
}
}
这题说是不能用1/x做但是注意下精度就没问题;反正我是这样的,不放心的你也可以用除法换算成乘法计算
放麦粒
你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬,
大臣说:请在第1个棋盘格放1粒麦子,在第2个棋盘格放2粒麦子,在第3个棋盘格放4粒
麦子,在第4个棋盘格放8粒麦子,......后一格的数字是前一格的两倍,直到放完所有
棋盘格(国际象棋共有64格)。
国王以为他只是想要一袋麦子而已,哈哈大笑。
当时的条件下无法准确计算,但估算结果令人吃惊:即使全世界都铺满麦子也不够用!
请你借助计算机准确地计算,到底需要多少粒麦子。
* 程序输出: 无
方法一:
import java.math.BigInteger;
/**
* @createDate:2019年3月12日 下午10:36:56
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:放麦子.java @describe:
*/
public class 放麦子 {
public static void main(String[] args) {
// TODO Auto-generated method stub
BigInteger sum = new BigInteger("1");
for (int i = 1; i <= 64; i++) {
sum = sum.multiply(BigInteger.valueOf(2));
}
sum = sum.subtract(BigInteger.ONE);
System.out.println(sum);
}
}
方法二:
import java.math.BigInteger;
/**
* @createDate:2019年3月12日 下午10:36:56
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:放麦子.java @describe:
*/
public class 放麦子 {
public static void main(String[] args) {
// TODO Auto-generated method stub
BigInteger sum = new BigInteger("0");
BigInteger rt = new BigInteger("2");
for (int i = 0; i < 64; i++) {
sum = sum.add(rt.pow(i));
}
System.out.println(sum);
}
}
更简单的理解方法
/**
* @createDate:2019年3月12日 下午11:48:44
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:放麦粒2.java @describe:
*/
public class 放麦粒2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 第一格的麦粒
BigInteger top = new BigInteger("1");
// 总的麦粒
BigInteger sum = new BigInteger("0");
//因为我们有第一格的麦粒,所以我们从第2格一直到64的总和
for (int i = 2; i <= 64; i++) {
top = top.multiply(BigInteger.valueOf(2));
sum = sum.add(top);
}
//加上第一个的麦粒数
sum = sum.add(BigInteger.valueOf(1));
//得出结果
System.out.println(sum);
}
}
总结:首先看到这题肯定没那么简单,结果你会发现你用long和int根本解不开这题,好了接下来说说解法,解法肯定是使用BigInteger超大整形类来解决问题。理解起来更简单的方法肯定是第三种,更符合常人逻辑、
猜年龄
今年的植树节(2012年3月12日),小明和他的叔叔还有小伙伴们一起去植树。休息
的时候,小明的同学问他叔叔多大年纪,他叔叔说:“我说个题目,看你们谁先猜出来!”
“把我出生的年月日连起来拼成一个8位数(月、日不足两位前补0)正好可以被今天
的年、月、日整除!”
他想了想,又补充到:“再给个提示,我是6月出生的。”
根据这些信息,请你帮小明算一下,他叔叔的出生年月日。
* 程序输出: 格式是年月日连成的8位数。 例如,如果是1948年6月12日,就写:19480612
* 程序头部的注释结束
/**
* @createDate:2019年3月13日 上午12:12:47
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:猜年龄.java @describe:
*/
public class 猜年龄 {
public static void main(String[] args) {
// TODO Auto-generated method stub
long temp;
for (int i = 1900; i <= 2012; i++) {
for (int j = 1; j <= 30; j++) {
temp = i * 10000 + 6 * 100 + j;
if (temp % 2012 == 0 && temp % 12 == 0) {
System.out.println(temp);
}
}
}
}
}
土地测量
造成高房价的原因有许多,比如土地出让价格。既然地价高,土地的面积必须仔细计算。遗憾的是,有些地块的形状不规则,比如是如图【1.jpg】中所示的五边形。
一般需要把它划分为多个三角形来计算。
已知三边求三角形的面积需要用海伦定理,参见【2.jpg】
各条边长数据如下:
AB = 52.1
BC = 57.2
CD = 43.5
DE = 51.9
EA = 33.4
EB = 68.2
EC = 71.9
/**
* @createDate:2019年3月13日 上午12:39:20
* @porjectName:lanqiao
* @author Static
* @version 1.0
* @since JDK 1.8.0_21
* @filename:土地测量.java @describe:
*/
public class 土地测量 {
public static void main(String[] args) {
// TODO Auto-generated method stub
double s1 = (52.1 + 33.4 + 68.2) / 2;
double s2 = (68.2 + 71.9 + 57.2) / 2;
double s3 = (51.9 + 71.9 + 43.5) / 2;
double A1 = Math.sqrt(s1 * (s1 - 52.1) * (s1 - 33.4) * (s1 - 68.2));
double A2 = Math.sqrt(s2 * (s2 - 68.2) * (s2 - 71.9) * (s2 - 57.2));
double A3 = Math.sqrt(s3 * (s3 - 51.9) * (s3 - 71.9) * (s3 - 43.5));
System.out.printf("%.2f", A1 + A2 + A3);
}
}