标签:
蓝桥杯网站修好了,今天才关注到,补上上次没有发的BASIC-20和开始今天的五道题:
【BASIC-20】 基础练习 数的读法
(虽然这题测试用例通过了,但这题写的代码仍然有bug,例如:43000403,我注释在代码处了,纠结的地方就是当块内结构是 "0_0_"如何处理,因为我的思路是块内遇到一个零就将“判断是否输出ling标志”置false了,所以20403结果是"er qian ling si bai san",初步解决方案是每次判断是否将“输出ling标志”置false时判断(除块内最后一位外)块内后面还有没有0,如果有0,则保留true值,但感觉这样很麻烦,如果有简便方法的朋友请指导我下,谢谢~)
Code:
import java.util.Scanner ; public class Main { // 局部判断从ch[start]~ch[end]是否全为'0',如果是,则后面不必在判断了(以免输出多个"ling"),例如1000300,看1的时候要看到十万位和万位是不是0,是的话直接输出yi bai wan就好了,而不是yi bai ling ling wan public static boolean isEnd( String str, int start, int end ) { char[] ch = str.toCharArray() ; boolean flag = true ; // 假定全为 '0' for( int i = start; i <= end; i ++ ) { if( ch[i] != '0' ) { flag = false ; break ; } } return flag ; } // 将数字转换成拼音 public static String num_string( int num) { switch( num ) { case 0: return "" ; case 1: return "yi" ; case 2: return "er" ; case 3: return "san" ; case 4: return "si" ; case 5: return "wu" ; case 6: return "liu" ; case 7: return "qi" ; case 8: return "ba" ; case 9: return "jiu" ; } return "ERROR" ; } public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner( System.in ) ; String str = sc.next() ; char[] ch = str.toCharArray() ; String result = "" ; boolean flag_shi = true ; // 做个标志,区分输出 "..... shi yi wan" 还是" .... yi shi yi wan"。例如: 110000-->"shi yi wan"(而不是"yi shi yi wan") ; 8110000-->"ba bai yi shi yi wan"(而不是ba bai shi yi wan) // 也就是说:当十万位 / 十位 前面有数字时且该位为 '1' 时输出"yi shi",否则只输出"shi" int start = 0 ; // 还未考虑怎么读ch的起始判断位置 int end = ch.length - 1 ; // 还未考虑怎么读ch的终了判断位置 if( ch[0] == '-' ) { // 负号处理 result += "fu " ; start ++ ; } while( start <= end ) { /** * 这里的思想是分块: * 第一块:十亿位、亿位 * 第二块:千万位、百万位、十万位、万位 * 第三块:千位、百位、十位、个位 * 原因:除非块内全零,否则第一块后一定会输出"yi" 第二块后一定会输出"wan" */ /** 第一块 部分**/ if( end >= 9 ) { // 十亿位 if( num_string( (int) (ch[start] - '0') ).equals("yi") ) { // 如果最高位是'1',则是"shi ...."而不是"yi shi ...." result += "shi" ; start ++ ; // 不要把这句话加到上两行的if中 ( if(num_string( (int) (ch[start++] - '0') ).equals("yi")) ),这样每当判断后无论正确与否start已经++修改了,这里应该只有当进入if才start ++ } else { result += num_string( (int) (ch[start++] - '0') ) + " shi " ; } if( isEnd( str, start, start + 1 ) ) { // 查看十亿位后第一块后面是否全为0。是,则直接字符串+"yi", 否,则看该块内的下一位 result += " yi " ; } flag_shi = false ; // 判断十万位和十位特殊处理时用 } if( end >= 8 ) { // 亿位 // if( isEnd( str, start, start ) ) { // 木有必要~ // result += "" ; // start ++; // } // else { result += num_string( (int) (ch[start ++] - '0') ) + " yi " ; // 亿位 // } if( isEnd( str, start, ch.length-1 ) ) { // 第一块处理完毕,看第二块、第三块是否全位0。是,则直接结束,否,则看下一位 break ; } flag_shi = false ; // 判断十万位和十位时特殊处理用 } /** 第二块部分**/ boolean flag_wan = true ; // 这里控制如果“万”部分有连续 ‘0’,只有第一个 0 会翻译成 "ling" ,例如:0010->ling yi shi if( end >= 7 ) { // 千万位 if( ch[start] == '0' ) { if( flag_wan ) { // 如果是第二块内第一次遇到 '0' result += "ling " ; flag_wan = false ; // 后面连续的 '0' 不再输出"ling" } start ++ ; } else { result += num_string( (int) (ch[start ++] - '0') ) +" qian " ; } if( isEnd( str, start, start + 2 ) ) { // 判断第二块内后面是否全为0 result += "wan " ; if( isEnd( str, start, str.length()-1 ) ) { // 如果第二块内全为0,但第三块还有数字,则输出一个"ling"再置false result += "ling " ; flag_wan = false ; // 让该块不再输出"ling" } } flag_shi = false ; // 判断十万位和十位时用 } if( end >= 6 ) { // 百万位 if( ch[start] == '0' ) { if( flag_wan ) { result += "ling " ; flag_wan = false ; } start ++ ; } else { result += num_string( (int) (ch[start ++] - '0') ) +" bai " ; } if( isEnd( str, start, start + 1 ) ) { // 检查第二块后面是否全为'0' result += "wan " ; if( isEnd( str, start, str.length()-1 ) ) { // 如果第二块内全为0,但第三块还有数字,则输出一个"ling"再置false result += "ling " ; flag_wan = false ; // 让该块不再输出"ling" } } flag_shi = false ; // 判断十万位和十位时用 } if( end >= 5 ) { // 十万位 if( ch[start] == '0' ) { if( flag_wan ) { result += "ling " ; flag_wan = false ; } start ++ ; } else { if( num_string( (int) (ch[start] - '0') ).equals("yi") && flag_shi) { // 如果十万位前面没有数字且该位为 '1' 则输出"shi"而不是"yi shi" result += "shi " ; start ++ ; flag_shi = false ; // 判断十万位和十位时用 } else { result += num_string( (int) (ch[start ++] - '0') ) +" shi " ; } } if( isEnd( str, start, start ) && flag_wan ) { // 查看万位是否为 0 result += "wan " ; // 这里有个 Bug!43000403 flag_wan = false ; // 让该块不再输出"ling" } } if( end >= 4 ) { // 万 if( ch[start] == '0' ) { if( flag_wan ) { result += " ling " ; flag_wan = false ; } start ++ ; } else { result += num_string( (int) (ch[start ++] - '0') ) +" wan " ; } if( isEnd( str, start, ch.length-1 ) ) { // 第二块处理完毕,检查后面是否全为 '0'。 是,则终止,否,则看下一位 break ; } } /** 第三块 部分**/ boolean flag_thousand = true ; // 这里控制如果“千百十个”部分有连续 ‘0’,只有第一个 0 会翻译成 "ling" ,例如:0023->ling er shi san if( end >= 3 ) { // 千位 if( ch[start] == '0' ) { if( flag_thousand ) { // 如果 result += "ling " ; flag_thousand = false ; } start ++ ; } else { result += num_string( (int) (ch[start ++] - '0') ) +" qian " ; } if( isEnd( str, start, ch.length-1 ) ) { break ; } } if( end >= 2 ) { // 白 if( ch[start] == '0' ) { if( flag_thousand && flag_wan ) { result += "ling " ; flag_thousand = false ; } start ++ ; } else { result += num_string( (int) (ch[start ++] - '0') ) +" bai " ; } if( isEnd( str, start, ch.length-1 ) ) { break ; } } if( end >= 1 ) { // 十 if( ch[start] == '0' ) { if( flag_thousand ) { result += "ling " ; flag_thousand = false ; } start ++ ; } else { if( num_string( (int) (ch[start] - '0') ).equals("yi") ) { result += " shi" ; start ++ ; } else { result += num_string( (int) (ch[start ++] - '0') ) +" shi " ; } } if( isEnd( str, start, ch.length-1 ) ) { break ; } } if( end >= 0 ) { // 个 (个位不需要"ling"判断) result += num_string( (int) (ch[start ++] - '0') ) ; } System.out.println( result ); System.exit(0); } System.out.println( result ); } }
【BASIC-21】 基础练习 Sine之舞
(这道题参考了http://blog.csdn.net/liangguojunainia/article/details/21484227 博文的代码和思路)
Code:
import java.util.Scanner ; public class Main { public static String An( int m, int n ) { if( m == n ) return "sin(" + m + ")" ; else return "sin(" + m + ( m%2==0 ? "+" : "-" ) + An( m+1, n ) + ")" ; } public static String Sn( String str, int m, int n ) { if( m > n ) return "" ; else return Sn( str, m+1, n ) + An( 1, n-m+1 ) + "+" + m ; } public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner( System.in ) ; int N = sc.nextInt() ; String str = "" ; str = Sn( str, 1, N ) ; System.out.println( str ); } }
【BASIC-22】 基础练习 FJ的字符串
(这道题参考了http://blog.csdn.net/hymanxq/article/details/25836453 博文的代码和思路,博主hymanxq采用递归的方法短小精悍,想了很久才领会,学习了~~)
Code:
import java.util.Scanner ; public class Main { private static String f( int n, String result ) { if( n == 1 ) { result += "A" ; return result ; } result += f( n-1, result ) +(char) ( 'A'+n-1) + f( n-1, result ) ; return result ; } public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner( System.in ) ; int N = sc.nextInt() ; String result = new String() ; result = f( N, result ) ; System.out.println( result ) ; } }
【BASIC-23】 基础练习 芯片测试
Code:
import java.util.Scanner ; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner( System.in ) ; int n = sc.nextInt() ; int[][] test = new int[n][n] ; int[] num_1 = new int[n] ; // 统计n个芯片好的次数 for( int i = 0; i < num_1.length; i ++ ) num_1[i] = 0 ; for( int i = 0; i < test.length; i ++ ) { for( int j = 0; j < test[i].length; j ++ ) { test[i][j] = sc.nextInt() ; if( test[i][j] == 1 ) num_1[j] ++ ; } } for( int i = 0; i < num_1.length; i ++ ) { if( num_1[i] > n/2 ) System.out.print( (i+1) + " " ) ; } System.out.println(); } }
【BASIC-24】 基础练习 龟兔赛跑预测
Code:
import java.util.Scanner ; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner( System.in ) ; int v1 = sc.nextInt() ; // 兔子的速度 int v2 = sc.nextInt() ; // 乌龟的速度 int t = sc.nextInt() ; // 任意一秒当兔子发现领先 t 米或 t 米以上时 int s = sc.nextInt() ; // 兔子就会歇下来休息 s 秒 int l = sc.nextInt() ; // 赛道长度 int d1 = 0 ; // 兔子跑过的路程 int d2 = 0 ; // 乌龟跑过的路程 int i = 0, j = 0 ; for( ; d1 < l && d2 < l; ) { d1 += v1 ; d2 += v2 ; i ++ ; if( d1 == l || d2 == l ) // 二者之一已经到达终点 break ; if( d1 - d2 >= t ) for( int k = 0; k < s && d2 < l; j ++, k ++ ) { // 兔子歇 s 秒,且期间要判断乌龟到没到达终点 d2 += v2 ; } } if( d1 == l && d2 == l ) // 平局 System.out.println( "D\n" + (i+j) ) ; else if( d1 == l ) // 兔子胜 System.out.println( "R\n" + (i+j) ) ; else if( d2 == l ) // 乌龟胜 System.out.println( "T\n" + (i+j) ) ; } }
【BASIC-25】 基础练习 回形取数
(这题自己写的代码超时了,所以参考了一些其他博文:
http://www.aichengxu.com/view/2460115:这篇博文代码也超时,但学习了另一种解题思路
http://www.cnblogs.com/watchfree/p/5307375.html:这篇博文代码测试通过
在这里小博有个疑问:同样的算法使用 C提交就可以通过,而且内存使用少很多,而使用Java就超时,这是因为语言编译执行的效率不同导致的吗?知道的朋友请求留个言哈~)
Code:(自己写的,代码可行但超时)
import java.util.Scanner ; public class Main { private static void display( int[][] A, boolean[][] flag, int m, int n ) { int i = -1, j = 0 ; int count = 0 ; // 走过数字的个数 while( count < n*m ) { // 如果还能向下的话继续循环 // 下 while( i+1<m && flag[i+1][j] ) { System.out.print( A[++i][j] + " " ) ; flag[i][j] = false ; } // 右 while( j+1<n && flag[i][j+1] ) { System.out.print( A[i][++j] + " " ) ; flag[i][j] = false ; } // 上 while( i-1 >= 0 && flag[i-1][j] ) { System.out.print( A[--i][j] + " " ) ; flag[i][j] = false ; } // 左 while( j-1 >= 0 && flag[i][j-1] ) { System.out.print( A[i][--j] + " " ) ; flag[i][j] = false ; } count ++ ; } } public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner( System.in ) ; int m = sc.nextInt() ; // 行 int n = sc.nextInt() ; // 列 int[][] A = new int[m][n] ; boolean[][] flag = new boolean[m][n] ; // 标志数组,true:没访问过,false:已访问 for( int i = 0; i < m; i ++ ) { for( int j = 0; j < n; j ++ ) { A[i][j] = sc.nextInt() ; flag[i][j] = true ; } } display( A, flag, m, n ) ; } }
Code:(参考代码http://www.aichengxu.com/view/2460115,另一种思路,可行但也超时)
import java.util.Scanner ; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner input=new Scanner(System.in); int m=input.nextInt() ; // m行 int n=input.nextInt(); // n 列 int[][] arr=new int[m][n] ; for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ arr[i][j]=input.nextInt(); } } int i=0 ; int j=0 ; for (i = 0; i < (n + 1) / 2 && i < (m + 1) / 2; i++) { for (j = i; j < m - i; j++) // 下 System.out.print(arr[j][i]+" "); for (j = i + 1; j < n - i; j++) // 右 System.out.print(arr[m - i - 1][j]+" "); if (n - i - 1 > i)/*(当n为奇数时最后一次循环只有左一列的数据。) 前面每进一次循环都读了对称的两列数据,前面i-1次循环读了2i个数据(i从0开始)在这次判断之前又读了一列数据 所以判断有没有对称的右列数据只要判断n-2*i-1是否大于0(等价于n - i - 1 > i) */ for (j = m - i - 2; j >= i; j--) // 上 System.out.print( arr[j][n - i - 1]+" "); if (m - i - 1 > i) for (j = n - i - 2; j > i; j--) // 左 System.out.print( arr[i][j]+" "); } } }
Code:(参考代码http://www.cnblogs.com/watchfree/p/5307375.html,算法同上,但用C编写的,通过)
#include <stdio.h> int main() { int m,n,i,j; int arr[210][210]; scanf("%d%d",&m,&n); for(i = 0; i < m; i++) for(j = 0; j < n; j++) scanf("%d",&arr[i][j]); for(i = 0; i < (m+1)/2 && i < (n+1)/2; i++) { for(j = i; j < m-i; j++) printf("%d ",arr[j][i]); for(j = i+1; j < n-i; j++ ) printf("%d ",arr[m-i-1][j]); if(n-i-1 > i) { for(j = m-i-2; j >= i; j--) printf("%d ",arr[j][n-i-1]); } if (m-i-1 > i) { for(j = n-i-2; j > i; j--) printf("%d ",arr[i][j]); } } return 0; }
叨叨叨:
题目越往后感觉思路越是跟不上,总是需要参考其他网站的代码,等有时间了我会修改所有【LQ系列】博文,适当配上文字思路,这样有助于众多访友们的理解和自己对题目的剖析。
这篇博文虽是原创,但也参考了很多其他博友的原创博文,如果转载请附上该博文中参考的原创博文链接,谢谢~
标签:
原文地址:http://blog.csdn.net/gohnn/article/details/51601726