(待续)
题目列表:
1-----报数游戏
2-----不连续处断开
3-----猜数字
4-----反转串
5-----第一个数字
6-----递归连续数
7-----股票风险
8-----括号问题
9-----公倍数
10---孪生素数
11---拍7游戏
12---排列平方数
(由于文章太长,所以可以用ctrl+F键来搜索题目)
1.报数游戏
有n个孩子站成一圈,从第一个孩子开始顺时针方向报数,报到3的人出列,下一个人继续从1报数,直到最后剩下一个孩子为止。问剩下第几个孩子。下面的程序以10个孩子为例,模拟了这个过程,请完善之(提示:报数的过程被与之逻辑等价的更容易操作的过程所代替)。
Vector a = new Vector();
for(int i=1; i<=10; i++)
{
a.add("第" + i + "个孩子");
}
for(;;)
{
if(a.size()==1) break;
for(int k=0; k<2; k++)
________________;
a.remove(0);
}
System.out.println(a);
结果:
[第4个孩子]
填写:
a.add(a.remove(0)
过程:
每一次把更新的序列的第一个和第二个丢到后面,然后接下来的第三个给删去…………
代码:
import java.util.Scanner;
import java.util.Vector;
public class Main {
public static void main(String[] args) {
Vector a = new Vector();
for(int i=1; i<=10; i++)
{
a.add("第" + i + "个孩子");//赋值
}
for(;;)
{
if(a.size()==1) break;//剩下最后一个孩子
//remove返回值为移除的元素,add把元素添加向量的末尾
for(int k=0; k<2; k++)//先把前面的两个元素放在后面
a.add(a.remove(0));//填空
a.remove(0);//再把第三个元素给删除了
}
System.out.println(a);
}
}
2.不连续处断开
下列代码运行结果为:
12345
23456
89
23456789
即把一个串从数字不连续的位置断开。试完善之。
String s = "12345234568923456789";
String t = "1";
for(int i=1; i<s.length(); i++)
{
if(s.charAt(i)==s.charAt(i-1)+1)
{
t += s.charAt(i);
}
else
{
System.out.println(t);
_____________________________;
}
}
System.out.println(t);
结果:
12345
23456
89
23456789
填写:
t += s.charAt(i)
代码如下:
import java.util.Scanner;
import java.util.Vector;
public class Main {
public static void main(String[] args) {
String s = "12345234568923456789";
String t = "1";
for(int i=1; i<s.length(); i++)
{
if(s.charAt(i)==s.charAt(i-1)+1)//如果是连续的
{
t += s.charAt(i);//子串
}
else//如果是不连续,清除t字符串,为下一次做准备
{
System.out.println(t);
t=""+s.charAt(i);//填空
}
}
System.out.println(t);
}
}
3.猜数字
很多人都玩过这个游戏:甲在心中想好一个数字,乙来猜。每猜一个数字,甲必须告诉他是猜大了,猜小了,还是刚好猜中了。下列的代码模拟了这个过程。其中用户充当甲的角色,计算机充当乙的角色。为了能更快地猜中,计算机使用了二分法。
阅读分析代码,填写缺失的部分。
把填空的答案(仅填空处的答案,不包括题面)存入考生文件夹下对应题号的“解答.txt”中即可。
System.out.println("请在心中想好一个数字(1~100),我来猜");
System.out.println("我每猜一个数字,你要告诉我是“猜大了”,“猜小了”,还是“猜中”");
Scanner scan = new Scanner(System.in);
int v1 = 1;
int v2 = 100;
for(;;)
{
int m = (v1 + v2)/2;
System.out.println("我猜是:" + m);
System.out.println("1.猜得太大了");
System.out.println("2.猜得太小了");
System.out.println("3.猜中!");
System.out.print("请选择:");
int user = Integer.parseInt(scan.nextLine());
if(user==3) break;
if(user==1) _____________;
if(user==2) _____________;
}
填空:
v2=m-1
v1=m+1
代码如下:
import java.util.Scanner;
import java.util.Vector;
public class Main {
public static void main(String[] args) {
System.out.println("请在心中想好一个数字(1~100),我来猜");
System.out.println("我每猜一个数字,你要告诉我是“猜大了”,“猜小了”,还是“猜中”");
Scanner scan = new Scanner(System.in);
int v1 = 1;
int v2 = 100;
for(;;)
{
int m = (v1 + v2)/2;
System.out.println("我猜是:" + m);
System.out.println("1.猜得太大了");
System.out.println("2.猜得太小了");
System.out.println("3.猜中!");
System.out.print("请选择:");
int user = Integer.parseInt(scan.nextLine());
if(user==3) break;
if(user==1) v2=m-1;//填空
if(user==2) v1=m+1;//填空
}
}
}
4.反转串
我们把“cba”称为“abc”的反转串。
求一个串的反转串的方法很多。下面就是其中的一种方法,代码十分简洁(甚至有些神秘),请聪明的你通过给出的一点点线索补充缺少的代码。
把填空的答案(仅填空处的答案,不包括题面)存入考生文件下对应题号的“解答.txt”中即可。
public static String reverseString(String x)
{
if(x==null || x.length()<2) return x;
return ____________________ + x.charAt(0);
}
填空:
reverseString(x.substring(1))+ x.charAt(0)
过程:
reverseString("abcde")=reverseString("bcde")+a =edcba
reverseString("bcde")=reverseString("cde")+b =edcb
reverseString("cde")=reverseString("de")+c =edc
reverseString("de")=reverseString("e")+d =ed
代码如下:
import java.util.Scanner;
public class Main {
public static String reverseString(String x)//abc
{
//substring:返回一个子字符串,该子字符串从指定索引处的字符开始到结尾
if(x==null || x.length()<2)
return x;//最后一个
return reverseString(x.substring(1))+ x.charAt(0);//不断地递归下去
}
public static void main(String[] args) {
System.out.println(reverseString("abcde"));
}
}
5.第一个数字
以下的静态方法实现了:把串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 ___________________; //填空
}
请分析代码逻辑,并推测划线处的代码。
答案写在 “解答.txt” 文件中
注意:只写划线处应该填的内容,划线前后的内容不要抄写。
结果:
2
过程:
(例1):
getFirstNum("abc24us43")=getFirstNum("bc24us43") = 2
getFirstNum("bc24us43")=getFirstNum("c24us43") = 2
getFirstNum("c24us43")=getFirstNum("24us43") = 2
(例2):
getFirstNum("ab")=getFirstNum("a") = -1
代码如下:
import java.util.Scanner;
public class Main {
public static int getFirstNum(String s)
{
if(s==null || s.length()==0) return -1;//如果找不到数字,返回-1
char c = s.charAt(0);
if(c>='0' && c<='9') return c-'0'; //填空 //第一个出现的数字的值返回
return getFirstNum(s.substring(1)); //填空 //递归,如果找不到,继续找
}
public static void main(String[] args) {
System.out.println(getFirstNum("abc24us43"));
}
}
6.递归连续数
以下程序打印出0~9的数字,请补充缺少的代码。
public class MyTest
{
public static void f(int begin, int end)
{
__________________;
System.out.println(begin);
f(begin+1, end);
}
public static void main(String[] args)
{
f(0,9);
}
}
填空:
if(begin==end) return;
代码如下:
import java.util.Scanner;
public class Main {
public static void f(int begin, int end)//0~9
{
if(begin==end) return;//填空 //写一个结束条件
System.out.println(begin);
f(begin+1, end);//与递归类似
}
public static void main(String[] args)
{
f(0,9);
}
}
7.股票风险
股票交易上的投机行为往往十分危险。假设某股票行为十分怪异,每天不是涨停(上涨10%)就是跌停(下跌10%)。
假设上涨和下跌的概率均等(都是50%)。再假设交易过程没有任何手续费。某人在开始的时候持有总价值为x的该股股票,
那么100个交易日后,他盈利的可能性是多少呢?
以下程序通过计算机模拟了该过程,一般的输出结果在0.3左右。请填写缺失的代码。
把填空的答案(仅填空处的答案,不包括题面)存入考生文件夹下对应题号的“解答.txt”中即可。
int N = 10000;
int n = 0;
for(int i=0; i<N; i++)
{
double value = 1000.0;
for(int k=0; k<100; k++)
{
if(Math.random() > _______)
value = value * 1.1;
else
value = value * 0.9;
}
if(____________) n++;
}
System.out.println(1.0*n/N);
填空:
0.5 value>1000
结果:
0.3079
代码如下:
class Main{
public static void main(String[] args) throws Exception {
int N = 10000;
int n = 0;
for(int i=0; i<N; i++)
{
double value = 1000.0;
for(int k=0; k<100; k++)
{
if(Math.random() > 0.5)//填空
value = value * 1.1;
else
value = value * 0.9;
}
if(value>1000) n++;//填空
}
System.out.println(1.0*n/N);
}
}
8.括号问题
所谓匹配是指不同类型的括号必须左右呼应,可以相互包含,但不能交叉
例如:
..(..[..]..).. 是允许的
..(...[...)....].... 是禁止的
对于 main 方法中的测试用例,应该输出:
false
true
false
false
import java.util.*;
public class A22
{
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(____________________) return false; // 填空
if(a.pop() != c) return false;
}
}
if(___________________) return false; // 填空
return true;
}
public static void main(String[] args)
{
System.out.println( isGoodBracket("...(..[.)..].{.(..).}..."));
System.out.println( isGoodBracket("...(..[...].(.).){.(..).}..."));
System.out.println( isGoodBracket(".....[...].(.).){.(..).}..."));
System.out.println( isGoodBracket("...(..[...].(.).){.(..)...."));
}
}
请分析代码逻辑,并推测划线处的代码。
答案写在 “解答.txt” 文件中
注意:只写划线处应该填的内容,划线前后的内容不要抄写。
填写:
a.empty() !a.empty()
代码如下:
import java.util.Stack;
public class Main
{
public static boolean isGoodBracket(String s)
{
//把需要待匹配的括号,压入栈顶部。把匹配好的括号,在栈中清除
Stack<Character> a = new Stack<Character>();//Character:char值
for(int i=0; i<s.length(); i++)
{
char c = s.charAt(i);
if(c=='(')
a.push(')');//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)
{
System.out.println( isGoodBracket("...(..[.)..].{.(..).}..."));
System.out.println( isGoodBracket("...(..[...].(.).){.(..).}..."));
System.out.println( isGoodBracket(".....[...].(.).){.(..).}..."));
}
}
9.公倍数
为什么1小时有60分钟,而不是100分钟呢?这是历史上的习惯导致。
但也并非纯粹的偶然:60是个优秀的数字,它的因子比较多。
事实上,它是1至6的每个数字的倍数。即1,2,3,4,5,6都是可以除尽60。
我们希望寻找到能除尽1至n的的每个数字的最小整数。
不要小看这个数字,它可能十分大,比如n=100, 则该数为:
69720375229712477164533808935312303556800
为此,有必要使用BigInteger来记录这样的大数。
请阅读下面的代码,填写缺失的部分(下划线部分)。
注意:请把填空的答案(仅填空处的答案,不包括题面)存入考生文件夹下对应题号的“解答.txt”中即可。
直接写在题面中不能得分。
import java.math.BigInteger;
public class My1
{
// 求能除尽1~n 每个数字的最小整数
public static BigInteger f(int n)
{
int[] x = new int[n+1];
for(int i=1; i<=n; i++) x[i] = i;
for(int i=2; i<n; i++)
{
for(int j=i+1; j<=n; j++)
{
if(x[j] % x[i]==0) _______________; // 填空1
}
}
BigInteger m = BigInteger.ONE;
for(int i=2; i<=n; i++)
{
m = m.multiply(__________________)); // 填空2
}
return m;
}
public static void main(String[] args)
{
System.out.println(f(30));
}
}
填空:
x[j] /= x[i] BigInteger.valueOf(x[i])
过程:
x[i]1 2 3 4 5 6 7 8 9
x[j] 2 3 2 5 1 7 2 3
2=2/1;
3=3/1;
2=4/2;
5=5/1;
1=6/3/2;
7=7/1;
8=8/2/2;
3=9/3;
代码如下:
import java.math.BigInteger;
public class Main
{
// 求能除尽1~n 每个数字的最小整数
public static BigInteger f(int n)
{
int[] x = new int[n+1];
for(int i=1; i<=n; i++)
x[i] = i;//1~30
for(int i=2; i<n; i++)//n=30
{
for(int j=i+1; j<=n; j++)
{
if(x[j] % x[i]==0) //如果能除尽
//后面的数除以之前的数,因为题目是求最小整数,像求最小公倍数
x[j] = x[j]/x[i]; // 填空1
}
}
BigInteger m = BigInteger.ONE;
for(int i=2; i<=n; i++)
{
m = m.multiply(BigInteger.valueOf(x[i])); // 填空2
}
return m;
}
public static void main(String[] args)
{
System.out.println(f(30));
}
}
10.孪生素数
所谓孪生素数指的就是间隔为 2 的相邻素数,它们之间的距离已经近得不能再近了,就象孪生兄弟一样。
最小的孪生素数是 (3, 5),在 100 以内的孪生素数还有 (5, 7), (11, 13), (17, 19), (29, 31), (41, 43), (59, 61) 和 (71, 73),总计有 8 组。
但是随着数字的增大,孪生素数的分布变得越来越稀疏,寻找孪生素数也变得越来越困难。那么会不会在超过某个界限之后就再也不存在孪生素数了呢?
孪生素数有无穷多对!这个猜想被称为孪生素数猜想,至今没有被严格证明。但借助于计算机我们确实可以找到任意大数范围内的所有孪生素数对。
下面的代码求出了正整数n以内(不含n)的所有孪生素数对的个数。比如,当n=100的时候,该方法返回8。试补全缺少的代码。
把填空的答案(仅填空处的答案,不包括题面)存入考生文件夹下对应题号的“解答.txt”中即可。
public static boolean isPrime(int x)
{
for(int i=2; i<=x/2; i++)
{
if(x%i==0) _____________;
}
return true;
}
public static int twinPrimeNum(int n)
{
int sum = 0;
for(int i=2; i<n; i++)
{
if(isPrime(i) && ___________) sum++;
}
return sum;
}
填空:
return false isPrime(i+2) && i+2<n
代码如下:
public class Main
{
public static boolean isPrime(int x)//判断素数
{
for(int i=2; i<=x/2; i++)//只要判断x的一半就行了
{
if(x%i==0) return false;
}
return true;
}
public static int twinPrimeNum(int n)
{
int sum = 0;
for(int i=2; i<n; i++)//2~100素数
{
if(isPrime(i) && isPrime(i+2) && i+2<n) sum++;//孪生质数
}
return sum;
}
public static void main(String[] args){
System.out.println(twinPrimeNum(100));
}
}
11.拍7游戏
许多人都曾经玩过“拍七”游戏。规则是:大家依次从1开始顺序数数,数到含有7或7的倍数的要拍手或其它规定的方式表示越过(比如:7,14,17等都不能数出),
下一人继续数下面的数字。违反规则者受罚。下面的程序模拟这个过程,拍7的情况输出“*”,请完善之。
for(int i=1; i<100; i++)
{
if(i % 7 == 0)
printf("*\n");
else if(___________________)
printf("*\n");
else
printf("%d\n", i);
}
填空:
i%10==7
代码如下:
public class Main
{
public static void main(String[] args){
for(int i=1; i<100; i++)
{
if(i % 7 == 0)//7的倍数
System.out.println("*\n");
else if(i%10 == 7)//取最后一位数(含7)
System.out.println("*\n");
else
System.out.printf("%d\n", i);
}
}
}
12.排列平方数
若干不同的数字,排列组合后能产生多少个平方数?
下面的代码解决了这个问题。
对于:1,6,9
排列后,可产生3个平方数:
169
196
961
请阅读下面的代码,填写缺失的部分(下划线部分)。
注意:请把填空的答案(仅填空处的答案,不包括题面)存入考生文件夹下对应题号的“解答.txt”中即可。
直接写在题面中不能得分。
public class My
{
public static void f(int[] a, int n)
{
if(n==a.length-1)
{
int k = 0;
for(int i=0; i<a.length; i++) k = ____________ + a[i]; // 填空1
int m = (int)(Math.sqrt(k)+0.5);
if(m*m==k)
{
System.out.println(k);
}
return;
}
for(int i=n; i<a.length; i++)
{
int t = a[n];
a[n] = a[i];
a[i] = t;
f(a, _______________); // 填空2
t = a[n];
a[n] = a[i];
a[i] = t;
}
}
public static void main(String[] args)
{
int[] a = {1,9,6};
f(a, 0);
}
}
填空:
k * 10 n+1
代码如下:
public class Main
{
public static void f(int[] a, int n)//196,0
{
if(n==a.length-1)
{
int k = 0;
for(int i=0; i<a.length; i++)
k = k * 10 + a[i]; // 填空1 //组成三位数
int m = (int)(Math.sqrt(k)+0.5);
if(m*m==k)//判断平方数
{
System.out.println(k);
}
return;
}
for(int i=n; i<a.length; i++)
{
//先调换位置
int t = a[n];
a[n] = a[i];
a[i] = t;
//实现了每一位数和另外几位数的调换
//下标0与1、2调换位置 //下标1与2调换位置
f(a, n+1);// 填空2
//之后调回来
t = a[n];
a[n] = a[i];
a[i] = t;
}
}
public static void main(String[] args)
{
int[] a = {1,9,6};
f(a, 0);
}
}
(待续)