跳到主要内容

2012蓝桥杯java高职题目分析

· 阅读需 17 分钟
Apache王也道长
软件开发者与技术作者

30年的改革开放,给中国带来了翻天覆地的变化。 2011全年中国手机产量约为11.72亿部。手机已经成为百姓的基本日用品! 给手机选个好听又好记的号码可能是许多人的心愿。 但号源有限,只能辅以有偿选号的方法了。 这个程序的目的就是:根据给定的手机尾号(4位),按照一定的规则来打分。 其规则如下:

本文保留原始赛题解答,并补充阅读方法:先明确输入输出约束,再选择数据结构和算法,最后用边界用例验证结果。旧赛题仍适合练习 Java 基础、枚举、字符串和数学推导。

  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.*;
public class T6 {
public static void main( String[] args )
{
Scanner sc = new Scanner( System.in );
System.out.print( "请输入行数:" );
int rows = sc.nextInt();
int score[] = new int[rows];
for ( int i = 0; i < rows; i++ )
{
String str = sc.next();
int a = Integer.parseInt( str.charAt( 0 ) + "" );
int b = Integer.parseInt( str.charAt( 1 ) + "" );
int c = Integer.parseInt( str.charAt( 2 ) + "" );
int d = Integer.parseInt( str.charAt( 3 ) + "" );
score[i] = test6( a, b, c, d );
}
for ( int i : score )
System.out.println( i );
}
public static int test6( int a, int b, int c, int d )
{
int score = 0;
/*不管升序还是降序,都加5分。例如:5678,4321都满足加分标准 */
if ( (a == b + 1 && b == c + 1 && c == d + 1) || (a == b - 1 && b == c - 1 && c == d - 1) )
score += 5;
/*
* 前三个数字相同,或后三个数字相同,都加3分。
* 例如:4888,6665,7777都满足加分的标准。
* 7777因为满足这条标准两次,所以这条规则给它加了6分。
*/
if ( a == b && b == c )
score += 3;
if ( b == c && c == d )
score += 3;
/*
* 符合AABB或者ABAB模式的加1分。例如:2255,3939,
* 7777因为满足这条标准两次,所以这条标准给它加了2分。
*/
if ( a == b && c == d )
score += 1;
if ( a == c && b == d )
score += 1;
/*
* 含有:6,8,9中任何一个数字,每出现一次加1分。
* 例如4326,6875,9918都符合加分标准。
* 其中,6875被加2分;9918被加3分。
*/
if ( a == 6 )
score += 1;
else if ( a == 8 )
score += 1;
else if ( a == 9 )
score += 1;
if ( b == 6 )
score += 1;
else if ( b == 8 )
score += 1;
else if ( b == 9 )
score += 1;
if ( c == 6 )
score += 1;
else if ( c == 8 )
score += 1;
else if ( c == 9 )
score += 1;
if ( d == 6 )
score += 1;
else if ( d == 8 )
score += 1;
else if ( d == 9 )
score += 1;
return(score);
}
}

在对银行账户等重要权限设置密码的时候,我们常常遇到这样的烦恼:如果为了好记用生日吧,容易被破解,不安全;如果设置不好记的密码,又担心自己也会忘记;如果写在纸上,担心纸张被别人发现或弄丢了… 这个程序的任务就是把一串拼音字母转换为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

/*
* 分析,先把每一个字符串存到二维数组中,然后把对应位置上的字符的ascii值相加
*/
import java.util.*;
public class T11 {
private static final int STRLEN = 6; /* 产生的密码长度 */
public static void main( String[] args )
{
Scanner sc = new Scanner( System.in );
System.out.print( "请输入行数:" );
int rows = sc.nextInt();
if ( rows < 100 )
{
System.out.println( "请输入" + rows + "行字符串:" );
String str[] = new String[rows]; /* 存储输入的字符串 */
String str2[] = new String[rows]; /* 存储返回来的密码的字符串 */
for ( int i = 0; i < rows; i++ )
{
str[i] = sc.next();
str2[i] = test11( str[i] );
}
System.out.println( "输出:" );
for ( String s : str2 )
{
System.out.println( s );
}
}else {
System.out.println( "请输入小于100的数!!" );
}
}
public static String test11( String string )
{
int stringLen = string.length();
int p = 0; /* 判断定义二维数组中一维的大小 */
if ( 0 != stringLen % STRLEN )
{
p = stringLen / STRLEN + 1;
}else if ( 0 == stringLen % STRLEN )
{
p = stringLen / STRLEN;
}
int asc[][] = new int[p][STRLEN]; /* 用来存储字符串中每一个字母的ascii值的数组 */
int asc2[] = new int[STRLEN]; /* 用来存储asc中对应位置的值的数组 */
int st = 0;
int nd = 0;
/* 把每一个字母的ascii值放入到二维数组中 */
for ( int i = 0; i < stringLen; i++ )
{
/* System.out.print((int)string.charAt(i)+" "); */
if ( st < p )
{
asc[st][nd] = (int) string.charAt( i );
nd++;
if ( STRLEN == nd )
{
st++;
nd = 0;
}
}
}
st = 0;
nd = 0;
int sum = 0;
/* 把对应位置上的ascii值相加放到数组中 */
while ( true )
{
if ( st < p )
{
/* System.out.println("st: " + st + " nd: " + nd); */
sum += asc[st][nd];
asc2[nd] = sum;
st++;
if ( p == st )
{
sum = 0;
st = 0;
nd++;
if ( STRLEN == nd )
break;
}
}
}
String result = "";
for ( int i = 0; i < asc2.length; i++ )
{
String tmp = asc2[i] + "";
String tmp2 = dg( tmp );
result += tmp2;
}
/*
* //---------------打印区域------------------
* System.out.println();
* for(int i=0;i<p;i++){
* for(int j=0;j<STRLEN;j++){
* System.out.printf("%3d ",asc[i][j]);
* }
* System.out.println();
* }
* System.out.println();
* for(int i : asc2){
* System.out.printf("%3d ",i);
* }
* //------------------------------------------
*/
return(result);
}
/* 数字缩位 */
public static String dg( String str )
{
if ( str != null || str != "" )
{
if ( 1 == str.length() )
{
return(str);
} else if ( 1 != str.length() )
{
int sum = 0;
for ( int i = 0; i < str.length(); i++ )
{
sum += Integer.parseInt( str.charAt( i ) + "" );
}
return(dg( sum + "" ) );
}
}
return(null);
}
}

今年的植树节(2012年3月12日),小明和他的叔叔还有小伙伴们一起去植树。休息的时候,小明的同学问他叔叔多大年纪,他叔叔说:“我说个题目,看你们谁先猜出来!” “把我出生的年月日连起来拼成一个8位数(月、日不足两位前补0)正好可以被今天的年、月、日整除!” 他想了想,又补充到:“再给个提示,我是6月出生的。” 根据这些信息,请你帮小明算一下,他叔叔的出生年月日。 答案写在“解答.txt”中,不要写在这里! 格式是年月日连成的8位数。 例如,如果是1948年6月12日,就写:19480612

/*
* 分析:循环逐一得到比较
*/
public class T12 {
public static void main( String[] args )
{
int birth = test();
System.out.println( "birth: " + birth );
}
public static int test()
{
for ( int i = 1900; i < 2012; i++ )
{
for ( int j = 1; j <= 30; j++ )
{
int birth = i * 10000 + 6 * 100 + j;
if ( 0 == birth % 2012 && 0 == birth % 12 && 0 == birth % 3 )
{
return(birth);
}
}
}
return(0);
}
}

你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬,大臣说: 请在第1个棋盘格放1粒麦子,在第2个棋盘格放2粒麦子, 在第3个棋盘格放4粒麦子,在第4个棋盘格放8粒麦子,…… 后一格的数字是前一格的两倍,直到放完所有棋盘格(国际象棋共有64格)。 国王以为他只是想要一袋麦子而已,哈哈大笑。 当时的条件下无法准确计算,但估算结果令人吃惊:即使全世界都铺满麦子也不够用! 请你借助计算机准确地计算,到底需要多少粒麦子。 答案写在“解答.txt”中,不要写在这里!

/*
* 分析:这个题目比较简单,不过注意数值越界
*/
public class T13 {
public static void main( String[] args )
{
double sum = test();
System.out.println( "sum=" + sum );
}
public static double test()
{
double sum = 0;
double a = 1;
for ( int i = 2; i <= 64; i++ )
{
a = a * 2;
sum += a;
}
return(sum + 1);
}
}

【编程题】(满分18分) 某少年宫引进了一批机器人小车。可以接受预先输入的指令, 按指令行动。小车的基本动作很简单, 只有3种:左转(记为L),右转(记为R),向前走若干厘米(直接记数字)。 例如,我们可以对小车输入如下的指令: 15L10R5LRR10R20 则,小车先直行15厘米,左转,再走10厘米,再右转,… 不难看出,对于此指令串,小车又回到了出发地。 你的任务是:编写程序,由用户输入指令, 程序输出每条指令执行后小车位置与指令执行前小车位置的直线距离。 【输入、输出格式要求】 用户先输入一个整数n(n<100),表示接下来将有n条指令。 接下来输入n条指令。每条指令只由L、R和数字组成(数字是0~100之间的整数) 每条指令的长度不超过256个字符。 程序则输出n行结果。 每条结果表示小车执行相应的指令前后位置的直线距离。要求四舍五入到小数后2位。 例如:用户输入: 5 L100R50R10 3LLL5RR4L12 LL 100R 5L5L5L5 则程序输出: 102.96 9.06 0.00 100.00 0.00 【注意】 请仔细调试!您的程序只有能运行出正确结果的时候才有机会得分! 请把所有类写在同一个文件中,调试好后, 存入与【考生文件夹】下对应题号的“解答.txt”中即可。 相关的工程文件不要拷入。 请不要使用package语句。 源程序中只能出现JDK1.5中允许的语法或调用。不能使用1.6或更高版本。

/*
* 分析:用坐标的方法,解析到得数字然后进行进行位移x,y 然后direction 换方向
*/
import java.util.*;
import java.util.regex.*;
public class T14_1 {
public static void main( String[] args )
{
Scanner sc = new Scanner( System.in );
System.out.print( "请输入指令条数(指令条数<100): " );
int x = sc.nextInt();
if ( x < 100 )
{
System.out.println( "请输入指令(指令的长度不超过256个字符): " );
String commands[] = new String[x];
Double result[] = new Double[x];
for ( int i = 0; i < x; i++ )
{
commands[i] = sc.next();
if ( commands[i].length() < 256 && Pattern.matches( "^[LR0-9]+$", commands[i] ) )
{
result[i] = test( commands[i] );
}else {
System.out.println( "输入的指令长度超过了256 或 指令不正确(每条指令只由L、R和数字组成(数字是0~100之间的整数))!!!" );
System.exit( 0 );
}
}
System.out.println( "输出: " );
for ( double d : result )
{
System.out.printf( "%.2f\n", d );
}
}else {
System.out.println( "输入的指令超过了100条!!!" );
}
}
public static double test( String command )
{
int direction = 1; /* 0 x负半轴 1 y正半轴 2 x正半轴 3 y负半轴 */
double x = 0;
double y = 0;
String str = "0";
int i = 0;
char temp;
while ( i < command.length() )
{
temp = command.charAt( i );
if ( temp >= '0' && temp <= '9' )
{
str += temp;
} else if ( 'L' == temp )
{
int length = Integer.parseInt( str );
switch ( direction )
{
case 0: x = x - length; break;
case 1: y = y + length; break;
case 2: x = x + length; break;
case 3: y = y - length; break;
}
str = "0";
direction = (direction - 1); /* 调整当前位置的方向 */
if ( direction == -1 )
{
direction = 3;
}
} else if ( 'R' == temp )
{
int length = Integer.parseInt( str );
switch ( direction )
{
case 0: x = x - length; break;
case 1: y = y + length; break;
case 2: x = x + length; break;
case 3: y = y - length; break;
}
str = "0";
direction = (direction + 1);
if ( direction == 4 )
{
direction = 0;
}
}
i++;
}
int length = Integer.parseInt( str );
switch ( direction )
{
case 0: x = x - length; break;
case 1: y = y + length; break;
case 2: x = x + length; break;
case 3: y = y - length; break;
}
return(Math.sqrt( x * x + y * y ) );
}
}

【编程题】(满分21分) Excel是最常用的办公软件。每个单元格都有唯一的地址表示。比如:第12行第4列表示为:“D12”,第5行第255列表示为“IU5”。

事实上,Excel提供了两种地址表示方法,还有一种表示法叫做RC格式地址。 第12行第4列表示为:“R12C4”,第5行第255列表示为“R5C255”。 你的任务是:编写程序,实现从RC地址格式到常规地址格式的转换。 【输入、输出格式要求】 用户先输入一个整数n(n<100),表示接下来有n行输入数据。 接着输入的n行数据是RC格式的Excel单元格地址表示法。 程序则输出n行数据,每行是转换后的常规地址表示法。 例如:用户输入: 2 R12C4 R5C255 则程序应该输出: D12 IU5

/*
* 分析,发现其中的规律就好做
*/
import java.util.*;
import java.util.regex.*;
public class T15 {
public static void main( String[] args )
{
Scanner sc = new Scanner( System.in );
System.out.print( "请输入一个整数n(n<100):" );
int x = sc.nextInt();
List<String> list = new ArrayList<String>();
if ( x < 100 )
{
int i = 0;
while ( i < x )
{
String temp = sc.next();
if ( Pattern.matches( "R\\d{1,3}C\\d{1,3}", temp ) )
{
list.add( temp );
i++;
}else {
System.out.println( "格式输入不正确!!" );
}
}
}else {
System.out.println( "输入数字大小超过了100!!!" );
System.exit( 0 );
}
String strs[] = new String[list.size()];
for ( int i = 0; i < list.size(); i++ )
{
String str = list.get( i );
strs[i] = test( str );
}
System.out.println( "输出:" );
for ( String s : strs )
{
System.out.println( s );
}
/*
* String transferStr = test("R5C255");
* System.out.println("transferStr: " + transferStr);
*/
}
public static String test( String str )
{
String transferStr = ""; /* 转换后的字符串 */
String transferStr1 = ""; /* 转换后的字符串后面的数字 */
int i = 0;
String tmp = "0";
char c;
while ( i < str.length() )
{
c = str.charAt( i );
if ( c >= '0' && c <= '9' )
{
tmp += c;
}else if ( 'C' == c )
{
int st = Integer.parseInt( tmp );
transferStr1 = st + ""; /* R后面的数字 */
tmp = "0";
}
i++;
}
int st = Integer.parseInt( tmp ); /* C后面的数字 */
StringBuffer sb = new StringBuffer();
char chs[] = new char[] {
'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z'
};
if ( st <= 26 )
{
sb.append( chs[st - 1] + "" );
}else {
int temp1 = st / 26 - 1;
int temp2 = st % 26 - 1;
sb.append( chs[temp1] + "" + chs[temp2] );
}
transferStr = sb.toString() + transferStr1;
return(transferStr);
}
}

【编程题】(满分34分) 某保密单位机要人员 A,B,C,D,E 每周需要工作5天,休息2天。 上级要求每个人每周的工作日和休息日安排必须是固定的,不能在周间变更。 此外,由于工作需要,还有如下要求:

  1. 所有人的连续工作日不能多于3天(注意:周日连到下周一也是连续)。
  2. 一周中,至少有3天所有人都是上班的。
  3. 任何一天,必须保证 A B C D 中至少有2人上班。
  4. B D E 在周日那天必须休息。
  5. A E 周三必须上班。
  6. A C 一周中必须至少有4天能见面(即同时上班)。 你的任务是:编写程序,列出ABCDE所有可能的一周排班情况。 工作日记为1,休息日记为0

A B C D E 每人占用1行记录,从星期一开始。 【输入、输出格式要求】 程序没有输入,要求输出所有可能的方案。 每个方案是7×5的矩阵。只有1和0组成。 矩阵中的列表示星期几,从星期一开始。 矩阵的行分别表示A,B,C,D,E的作息时间表。 多个矩阵间用空行分隔开。 例如,如下的矩阵就是一个合格的解。请编程输出所有解(多个解的前后顺序不重要)。 0110111 1101110 0110111 1101110 1110110

/*
* 分析:先根据要求一和题目可以得出一下组合然后得出组合
* 然后再去满足其余的要求
*/
public class T16 {
/* 根据 要求一和题目可以得出一下组合 */
static String[] strs = new String[] { "1110110", "1101110", "1101101",
"1011101", "1011011", "0110111", "0111011" };
public static void main( String[] args )
{
test();
}
public static void test()
{
int k = 0;
String members[] = new String[5];
for ( int a = 0; a < 7; a++ )
{
for ( int b = 0; b < 7; b++ )
{
for ( int c = 0; c < 7; c++ )
{
for ( int d = 0; d < 7; d++ )
{
for ( int e = 0; e < 7; e++ )
{
members[0] = strs[a];
members[1] = strs[b];
members[2] = strs[c];
members[3] = strs[d];
members[4] = strs[e];
if ( check( members ) )
{
k++;
System.out.println( "第" + k + "种方案:" );
print( members );
}
}
}
}
}
}
}
public static void print( String members[] )
{
for ( int i = 0; i < members.length; i++ )
{
System.out.print( members[i] );
System.out.println();
}
}
public static boolean check( String members[] )
{
if ( check2( members ) && check3( members ) && check5( members )
&& check4( members ) && check6( members ) )
{
return(true);
}
return(false);
}
/* 要求二 */
public static boolean check2( String members[] )
{
int sum = 0;
for ( int j = 0; j < 7; j++ )
{
int count = 0;
for ( int i = 0; i < members.length; i++ )
{
if ( members[i].charAt( j ) == '1' )
{
count++;
}
}
if ( count == 5 )
{
sum++;
}
}
if ( sum == 3 )
{
return(true);
}
return(false);
}
/* 要求三 */
public static boolean check3( String members[] )
{
for ( int i = 0; i < 7; i++ )
{
int count = 0;
for ( int j = 0; j < 4; j++ )
{
if ( members[j].charAt( i ) == '1' )
{
count++;
}
}
if ( count < 2 )
{
return(false);
}
}
return(true);
}
/* 要求四 */
public static boolean check4( String members[] )
{
if ( members[1].charAt( 6 ) == '0' && members[3].charAt( 6 ) == '0'
&& members[4].charAt( 6 ) == '0' )
{
return(true);
}
return(false);
}
/* 要求五 */
public static boolean check5( String members[] )
{
if ( members[0].charAt( 2 ) == '1' && members[4].charAt( 2 ) == '1' )
{
return(true);
}
return(false);
}
/* 要求六 */
public static boolean check6( String members[] )
{
int count = 0;
for ( int i = 0; i < 7; i++ )
{
if ( members[0].charAt( i ) == '1' && members[2].charAt( i ) == '1' )
{
count++;
}
}
if ( count >= 4 )
{
return(true);
}
return(false);
}
}

本文阅读量:--

总访问量 -- · 访客数 --