蓝桥杯网站修好了,今天才关注到,补上上次没有发的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