【LQ系列】 BASIC-26~BASIC-30

首先祝贺所有高考学子们圆满完成考试,CHEER UP !


开始正题:赶着今天最后的末班车,做完了今天的5道题:


【BASIC-26】 基础练习 报时助手 

问题描述

  给定当前的时间,请用英文的读法将它读出来。
  时间用时h和分m表示,在英文的读法中,读一个时间的方法是:
  如果m为0,则将时读出来,然后加上“o'clock”,如3:00读作“three o'clock”。
  如果m不为0,则将时读出来,然后将分读出来,如5:30读作“five thirty”。
  时和分的读法使用的是英文数字的读法,其中0~20读作:
  0:zero, 1: one, 2:two, 3:three, 4:four, 5:five, 6:six, 7:seven, 8:eight, 9:nine, 10:ten, 11:eleven, 12:twelve, 13:thirteen, 14:fourteen, 15:fifteen, 16:sixteen, 17:seventeen, 18:eighteen, 19:nineteen, 20:twenty。
  30读作thirty,40读作forty,50读作fifty。
  对于大于20小于60的数字,首先读整十的数,然后再加上个位数。如31首先读30再加1的读法,读作“thirty one”。
  按上面的规则21:54读作“twenty one fifty four”,9:07读作“nine seven”,0:15读作“zero fifteen”。
输入格式
  输入包含两个非负整数h和m,表示时间的时和分。非零的数字前没有前导0。h小于24,m小于60。
输出格式
  输出时间时刻的英文。
样例输入
0 15
样例输出
zero fifteen



Code:

import java.util.Scanner ;

public class Main {

	private static String numToString( int num ) {
		String str = new String() ;
		switch( num ) {
		case 0 :		str = "zero" ;		break ;
		case 1 :		str = "one" ;		break ;
		case 2 :		str = "two" ;		break ;
		case 3 :		str = "three" ;	break ;
		case 4 :		str = "four" ;		break ;
		case 5 :		str = "five" ;		break ;
		case 6 :		str = "six" ;		break ;
		case 7 :		str = "seven" ;			break ;
		case 8 :		str = "eight" ;			break ;
		case 9 :		str = "nine" ;				break ;
		case 10 :		str = "ten" ;			break ;
		case 11 :		str = "eleven" ;	break ;
		case 12 :		str = "twelve" ;	break ;
		case 13 :		str = "thirteen" ;	break ;
		case 14 :		str = "fourteen" ;	break ;
		case 15 :		str = "fifteen" ;		break ;
		case 16 :		str = "sixteen" ;	break ;
		case 17 :		str = "seventeen" ;		break ;
		case 18 :		str = "eighteen" ;	break ;
		case 19 :		str = "nineteen" ;	break ;
		case 20 :		str = "twenty" ;	break ;
		case 30 :		str = "thirty" ;		break ;
		case 40 :		str = "forty" ;		break ;
		case 50 :		str = "fifty" ;		break ;
		case 60 :		str = "sixty" ;		break ;
		default :		str = "ERROR" ;
		}
		return str ;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner( System.in ) ;
		int h = sc.nextInt() ;	// 时
		int m = sc.nextInt() ;	// 分
		if( h <= 20 ) 
			System.out.print( numToString(h) + " " ) ;
		else {
			int h_1 = h / 10 * 10 ;
			int h_2 = h % 10 ;
			System.out.print( numToString(h_1) + " " + numToString(h_2) + " " ) ;
		}
	 	if( m > 0 && ( m <= 20 || m % 10 == 0 ) )		// m<20 || m == 20, 30, 40, 50, 60
			System.out.println( numToString(m) ) ;
		else if( m == 0 )
			System.out.println( "o'clock" );
		else	{	
			int m_1 = m / 10 * 10 ;		// m 的十位
			int m_2 = m % 10 ;		// m 的个位
			System.out.println( numToString(m_1) + " " + numToString( m_2 ) ) ;
		}
	}

}



【BASIC-27】 基础练习 2n皇后问题 


问题描述
  给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。
输入格式
  输入的第一行为一个整数n,表示棋盘的大小。
  接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
输出格式
  输出一个整数,表示总共有多少种放法。
样例输入
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出
2
样例输入
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出
0

(参考代码1:http://www.th7.cn/Program/cp/201601/745092.shtml

    参考代码2:https://www.jurieo.com/1027.html#respond

    参考思路1:http://blog.csdn.net/stephan14/article/details/44150713)


(这道题中n_queue函数中的有几句没看明白,我标在代码处了,麻烦大家看懂的在底下留个言~)



import java.util.Scanner ;

public class Main {
	
	private static int solution = 0 ;	// 解法个数
	
	private static boolean p( int n, int x, int y, int[][] A, int s ) {
		/**
		 *  n: A的阶数
		 *  x: 当前已经判断到了 x 行放皇后问题
		 *  y: 列坐标
		 *  A: 矩阵
		 *  s: 皇后位置要赋的值
		 */
		int i, j ;
		for( i = x-1; i>=0; i -- ) {
			if( A[i][y] == s )	// 同一列有皇后
				return false ;
		}
		for( i = x-1, j=y-1; i>=0 && j>=0; i--, j-- ) {	
			if( A[i][j] == s )		// 平行于正对角线处(左上)有皇后
				return false ;
		}
		for( i = x-1, j=y+1; i>=0 && j<n; i--, j++ ) {
			if( A[i][j] == s )		// 平行于反对角线处(右上)有皇后
				return false ;
		}
		return true ;
	}
	
	private static int n_queen( int n, int x, int[][] A, int s ) {
		/**
		 * 	n: A[][]的阶数
		 * 	x: 行坐标
		 * 	A: 矩阵
		 * 	s: ???
		 */
		int i ;
		if( x == n ) {	// 如果已经判断到最后一行了,则找到结果了
			/********这两行是什么意思?*********/
			if( s == 2 )
				n_queen(n, 0, A, 3 ) ;
			/*****************************/
			else
				solution ++ ;
			return 0 ;
		}
		for( i = 0; i < n; i ++) {
			if( A[x][i] != 1 )	// 如果A[x][i] 不为1则为0,说明该位置不可以放皇后
				continue ;
			if( p(n, x, i, A, s) )		// check条件检查
				A[x][i] = s ;
			else		// 不满足条件则判断该行下一个结点是否可以放皇后
				continue ;
			n_queen(n, x+1, A, s ) ;	// 判断下一行的皇后位置
			A[x][i] = 1 ;		// 回溯
		}
		return 0 ;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner( System.in ) ;
		int n = sc.nextInt() ;
		int[][] A = new int[n][n] ;
		for( int i = 0; i < n; i ++ ) {
			for( int j = 0; j < n; j ++ ) {
				A[i][j] = sc.nextInt() ;
			}
		}
		n_queen( n, 0, A, 2 ) ;
		System.out.println( solution ) ;
	}

}



【BASIC-28】 基础练习 Huffuman树


问题描述
  Huffman树在编码中有着广泛的应用。在这里,我们只关心Huffman树的构造过程。
  给出一列数{ pi}={ p 0, p 1, …, pn -1},用这列数构造Huffman树的过程如下:
  1. 找到{ pi}中最小的两个数,设为 papb,将 papb从{ pi}中删除掉,然后将它们的和加入到{ pi}中。这个过程的费用记为 pa + pb
  2. 重复步骤1,直到{ pi}中只剩下一个数。
  在上面的操作过程中,把所有的费用相加,就得到了构造Huffman树的总费用。
  本题任务:对于给定的一个数列,现在请你求出用该数列构造Huffman树的总费用。

  例如,对于数列{ pi}={5, 3, 8, 2, 9},Huffman树的构造过程如下:
  1. 找到{5, 3, 8, 2, 9}中最小的两个数,分别是2和3,从{ pi}中删除它们并将和5加入,得到{5, 8, 9, 5},费用为5。
  2. 找到{5, 8, 9, 5}中最小的两个数,分别是5和5,从{ pi}中删除它们并将和10加入,得到{8, 9, 10},费用为10。
  3. 找到{8, 9, 10}中最小的两个数,分别是8和9,从{ pi}中删除它们并将和17加入,得到{10, 17},费用为17。
  4. 找到{10, 17}中最小的两个数,分别是10和17,从{ pi}中删除它们并将和27加入,得到{27},费用为27。
  5. 现在,数列中只剩下一个数27,构造过程结束,总费用为5+10+17+27=59。
输入格式
  输入的第一行包含一个正整数 nn<=100)。
  接下来是 n个正整数,表示 p 0, p 1, …, pn -1,每个数不超过1000。
输出格式
  输出用这些数构造Huffman树的总费用。
样例输入
5
5 3 8 2 9
样例输出
59


Code:

import java.util.Arrays;
import java.util.Scanner ;

public class Main {

	private static int Huffman( int[] A, int n ) {
		int fee = 0 ;
		for( int i = 0; i < n; i ++ ) {
			Arrays.sort(A) ;
			if( A[1] == Integer.MAX_VALUE ) 	// 如果A[1]=Integer.MAX_VALUE,则说明A中只有A[0]是正常数(即最终结果)
				break ;
			fee +=A[0] + A[1] ;
			A[1] = A[0] + A[1] ;		// 把最小的两个元素相加结果加到A中
			A[0] = Integer.MAX_VALUE ;
		}
		return fee ;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner( System.in ) ;
		int n = sc.nextInt() ;
		int[] A = new int[n] ;
		for( int i = 0; i < n; i ++ ) 
			A[i] = sc.nextInt() ;
		
		System.out.println( Huffman( A, n ) ) ;
	}

}



【BASIC-29】 基础练习 高精度加法 


问题描述
  输入两个整数 ab,输出这两个整数的和。 ab都不超过100位。
算法描述
  由于 ab都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。
  定义一个数组 AA[0]用于存储 a的个位, A[1]用于存储 a的十位,依此类推。同样可以用一个数组 B来存储 b
  计算 c = a + b的时候,首先将 A[0]与 B[0]相加,如果有进位产生,则把进位(即和的十位数)存入 r,把和的个位数存入 C[0],即 C[0]等于( A[0]+ B[0])%10。然后计算 A[1]与 B[1]相加,这时还应将低位进上来的值 r也加起来,即 C[1]应该是 A[1]、 B[1]和 r三个数的和.如果又有进位产生,则仍可将新的进位存入到 r中,和的个位存到 C[1]中。依此类推,即可求出 C的所有位。
  最后将 C输出即可。
输入格式
  输入包括两行,第一行为一个非负整数 a,第二行为一个非负整数 b。两个整数都不超过100位,两数的最高位都不是0。
输出格式
  输出一行,表示 a + b的值。
样例输入
20100122201001221234567890
2010012220100122
样例输出
20100122203011233454668012


Code:

import java.math.BigInteger;
import java.util.Scanner ;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner( System.in ) ;
		String str1 = sc.next() ;
		String str2 = sc.next() ;
		BigInteger a1 = new BigInteger( str1 ) ;
		BigInteger a2 = new BigInteger( str2 ) ;
		System.out.println( a1.add(a2) ) ;
	}

}


【BASIC-30】 基础练习 阶乘计算


问题描述
  输入一个正整数 n,输出 n!的值。
  其中 n!=1*2*3*…* n
算法描述
   n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组 A来表示一个大整数 aA[0]表示 a的个位, A[1]表示 a的十位,依次类推。
  将 a乘以一个整数 k变为将数组 A的每一个元素都乘以 k,请注意处理相应的进位。
  首先将 a设为1,然后乘2,乘3,当乘到 n时,即得到了 n!的值。
输入格式
  输入包含一个正整数 nn<=1000。
输出格式
  输出 n!的准确值。
样例输入
10
样例输出
3628800


Code:

import java.math.BigInteger;
import java.util.Scanner ;

public class Main {

	private static BigInteger factorial( int n ) {
		BigInteger result = new BigInteger( "1" ) ;
		for( int i = 1; i <= n; i ++) {
			result = result.multiply( new BigInteger( String.valueOf(i) ) ) ;
		}
		return result ;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner( System.in ) ;
		String str = sc.next() ;
		
		System.out.println( factorial( Integer.parseInt(str) ) ) ;
	}

}



至此,基础练习30道题全部完成,感觉有些对我来说还是有一些考验性,今天的后两道题我直接用的BigInteger做的,C/C++中我不知道有没有这么方便的东西,Java的BigInteger和BigDecimal实在是很方便,如果用C/C++编写一个模拟加法应该不是很困难,模拟阶乘估计稍难一些,有时间我发一下C/C++版的,欢迎大家批评指正~有其他思路或有更好更快的算法欢迎在下面评论~~


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值