- 入门
- 简单
- HJ11:数字颠倒
- HJ12:字符串反转
- HJ22:汽水瓶
- HJ37:统计每个月兔子的总数
- HJ50:四则运算
- HJ53:iNOC产品部-杨辉三角的变形
- HJ54:表达式求值
- HJ56:iNOC产品部—完全数计算
- HJ62:查找输入整数二进制中1的个数
- HJ73:计算日期到天数转换
- HJ72:百钱买百鸡问题
- HJ66:配置文件恢复
- HJ61:放苹果
- HJ108:求最小公倍数
- HJ12:字符串反转
- HJ83:二维数组操作
- HJ84:统计大写字母个数
- HJ75:公共字串计算
- HJ76:尼科彻斯定理
- HJ86:求最大连续bit数
- HJ85:字符串运用-密码截取(最长回文字符串)
- HJ74:参数解析
- HJ87:密码强度等级
- HJ100:等差数列
- HJ91:走方格的方案数
- 中等
入门
HJ7:取近视值
写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。
输入描述:
输入一个正浮点数值
输出描述:
输出该数值的近似整数值
示例1
输入
5.5
输出
6
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
double doubleNum=scanner.nextDouble();
System.out.println((int)(doubleNum+0.5));
scanner.close();
}
}
HJ15:求int型数据在内存中存储时1的个数
输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。
输入描述:
输入一个整数(int类型)
输出描述:
这个数转换成2进制后,输出1的个数
示例1
输入
5
输出
2
//方式1:二进制,使用与运算与移位运算来解题
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
int count=0;
while(num>0){
if((num&1)==1){
count++;
}
num>>>=1;
}
System.out.println(count);
scanner.close();
}
}
//方式2:巧妙运用 n&(n-1) 能够消除掉n中的倒数第一个1,来计算n里包含1的个数
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
int count=0;
while(num>0){
count++;
num=num&(num-1);
}
System.out.println(count);
scanner.close();
}
}
//方式3:使用java中的方法 Integer.bitCount(int n);
import java.util.Scanner;
import java.lang.Integer;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
System.out.println(Integer.bitCount(num));
scanner.close();
}
}
简单
HJ11:数字颠倒
输入一个整数,将这个整数以字符串的形式逆序输出
程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001
输入描述:
输入一个int整数
输出描述:
将这个整数以字符串的形式逆序输出
示例1
输入
1516000
输出
0006151
//情况1: a%10取个位然后输出,a/=10去掉个位,循环直到输出所有数字。
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
do{//使用do-while循环是考虑了输入是0的情况
System.out.printnum%10);// System.out.print()输出的直接就是字符串的形式
num/=10;
}while(num>0);
scanner.close();
}
}
情况2:把这个整数转为字符串,使用charAt(index)进行逆序输出
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
String numStr=num+"";
for(int i=numStr.length()-1;i>=0;i--){
System.out.print(numStr.charAt(i));
}
scanner.close();
}
}
情况3:把这个整数转为字符串,进行逆序交换前半段和后半段的字符
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
char[] chArr=(num+"").toCharArray();
int len=chArr.length;
for(int i=0,j=len-1;i<j;i++,j--){
char temp=chArr[i];
chArr[i]=chArr[j];
chArr[j]=temp;
}
System.out.println(new String(chArr));
scanner.close();
}
}
HJ12:字符串反转
接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)
输入描述:
输入一行,为一个只包含小写字母的字符串。
输出描述:
输出该字符串反转后的字符串。
示例1
输入
abcd
输出
dcba
//方式1:直接利用字符串的charAt(index)方法逆序输出字符串中的每个字符
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String str=scanner.next();
for(int i=str.length()-1;i>=0;i--){
System.out.print(str.charAt(i));
}
scanner.close();
}
}
//方式2:将输入的字符串转为字符数组,然后进行逆序交换前半段和后半段的字符
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String str=scanner.next();
char[] chArr=str.toCharArray();
for(int i=0,j=chArr.length-1;i<j;i++,j--){
char temp=chArr[i];
chArr[i]=chArr[j];
chArr[j]=temp;
}
System.out.println(new String(chArr));
scanner.close();
}
}
HJ22:汽水瓶
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
输入描述:
输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=100),表示小张手上的空汽水瓶数。n=0表示输入结束,你的程序不应当处理这一行。
输出描述:
对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。
示例1
输入
3
10
81
0
输出
1
5
40
//方式1:如果是n个空瓶换一杯水,那么就说明n-1空瓶就可以喝一份水,如果有m个空瓶,那么可以喝到m/(n-1)份水
//此题实际上是两个空瓶就可以喝到一个新饮料
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(true){
int num=scanner.nextInt();
if(num==0) break;
System.out.println(num/2);
}
scanner.close();
}
}
//方式2:根据题干我写出来的傻缺办法
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int num=0;
int res=0;
while(true){
num=scanner.nextInt();
if(num==0) break;
while(num>2){
res+=num/3;
num=num/3+num%3;
}
if(num==2) res+=1;
System.out.println(res);
res=0;
}
scanner.close();
}
}
HJ37:统计每个月兔子的总数
有一只兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子,假如兔子都不死,问每个月的兔子总数为多少?
本题有多组数据。
输入描述:
输入int型表示month
输出描述:
输出兔子总数int型
示例1
输入
9
输出
34
//实际是一个斐波那契数列的问题
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int month=scanner.nextInt();
int f1=0,f2=1,temp=f1+f2;
for(int i=2;i<=month;i++){
temp=f1+f2;
f1=f2;
f2=temp;
}
System.out.println(f2);
}
scanner.close();
}
}
HJ50:四则运算
输入一个表达式(用字符串表示),求这个表达式的值。
保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。
输入描述:
输入一个算术表达式
输出描述:
得到计算结果
示例1
输入
3+2{1+2[-4/(8-6)+7]}
输出
25
*题解:
消消乐解法:
第一步,先考虑无括号的情况,先乘除后加减,这个用栈很容易解决,遇到数字先压栈,如果下一个是乘号或除号,先出栈,和下一个数进行乘除运算,再入栈,最后就能保证栈内所有数字都是加数,最后对所有加数求和即可。
第二步,遇到左括号,直接递归执行第一步即可,最后检测到右括号,返回括号内的计算结果,退出函数,这个结果作为一个加数,返回上一层入栈。
import java.util.Scanner;
import java.util.LinkedList;
/**
* 3+2*{1+2*[-4/(8-6)+7]}
*
* 1.数字的两边肯定是符号
* 2.
*
*/
public class Main{
//四则运算表达式的长度,全局只有一个,从0索引开始取到表达式的末尾,定义为全局的
private static int pos;
//数组的长度也是固定的,全局只有一个,定义为全局的
private static int len;
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
char[] data=scanner.next().toCharArray();
len=data.length;
System.out.println(compute(data));
scanner.close();
}
private static int compute(char[] data){
LinkedList<Integer> stack=new LinkedList<>();//用到了递归运算,则每递归一次则进行一次造新栈
char flag='+';//flag表示pos索引取到的是+、-、*、/运算符
int num=0;//num表示pos索引取到的是数字
while(pos<len){
//如果遇到左括号,则对一对括号里面的数字进行递归运算处结果
if(data[pos]=='('||data[pos]=='['||data[pos]=='{'){
pos++;//时刻记得取完数组里的一位,则移动索引
num=compute(data);
}
while(pos<len&&(data[pos]>='0'&&data[pos]<='9')){//时刻记得不要让数组越界
num=num*10+(data[pos]-'0');//数字可能是百位或者千位数字,所以需要循环取出来
pos++;
}
//**** 此处是把数字存入栈中,操作完数字,下一位一定是符号,一定要及时取出下一位 ****
switch(flag){//此处用栈实现不带括号的加减乘除运算
case '+':
stack.addLast(num);
break;
case '-':
stack.addLast(-num);
break;
case '*':
int temp=stack.getLast()*num;
stack.removeLast();
stack.addLast(temp);
break;
case '/':
int temp1=stack.getLast()/num;
stack.removeLast();
stack.addLast(temp1);
break;
}
//*************************************************************
num=0;//此处的num=0是非常有必要的,因为要让num=0,下一位num=num*10+(data[pos]-'0');才不会出错
if(pos<len){//时刻注意不要让数组越界
flag=data[pos];
//如果遇到右括号,则结束当前的递归
if(data[pos]==')'||data[pos]==']'||data[pos]=='}'){
pos++;
break;
}
pos++;//如果没有进入上面判断右括号的if语句,需要后移一位数组的索引,因为if前面进行了取符号操作flag=data[pos]
}
}
int res=0;//当走到这里时,每次递归到pos=len,把当前栈中的所有数字进行加法运算,算出最后的结果返回传递到上一级栈中
while(!stack.isEmpty()){
res+=stack.getFirst();
stack.removeFirst();
}
return res;
}
}
HJ53:iNOC产品部-杨辉三角的变形
1
1 1 1
1 2 3 2 1
1 3 6 7 6 3 1
1 4 10 16 19 16 10 4 1
以上三角形的数阵,第一行只有一个数1,以下每行的每个数,是恰好是它上面的数,左上角数到右上角的数,3个数之和(如果不存在某个数,认为该数就是0)。
求第n行第一个偶数出现的位置。如果没有偶数,则输出-1。例如输入3,则输出2,输入4则输出3。
输入n(n <= 1000000000)
本题有多组输入数据,输入到文件末尾,请使用while(cin>>)等方式读入
输入描述:
输入一个int整数
输出描述:
输出返回的int值
示例1
输入
4
2
输出
3
-1
题解:
本题是找规律的题,只要往下再写几行就可以看出奇偶的规律,而且每行只需要写前几个就可以了,因为题目问的是第一个偶数的index。于是我们会发现,只有n为1,2时,没有出现偶数,剩下的按照2 3 2 4的规律每四行循环一次。
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int num=scanner.nextInt();
if(num<=2) //找规律:在1、2行为-1,其余行按 2、3、2、4的规律进行分布
System.out.println(-1);
else if(num%4==0)
System.out.println(3);
else if(num%4==1||num%4==3)
System.out.println(2);
else if(num%4==2)
System.out.println(4);
}
scanner.close();
}
}
HJ54:表达式求值
给定一个字符串描述的算术表达式,计算出结果值。
输入字符串长度不超过100,合法的字符包括”+, -, , /, (, )”,”0-9”,字符串内容的合法性及表达式语法的合法性由做题者检查。本题目只涉及整型计算。
输入描述:
输入算术表达式
输出描述:
计算出结果值
示例1
输入
400+5
输出
405
*题解:重点在于运用了正则表达式来匹配
String pattern = "[\\d|()()|+\\-*/]";
if (Pattern.compile(pattern).matcher(str).find()){
char[] data = str.toCharArray(); // 转换表达式
len=data.length;
System.out.println(compute(data));// 计算结果
} else
System.out.println(-1);
import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Pattern;
public class Main{
private static int pos;
private static int len;
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String str=scanner.next();
String pattern = "[\\d|()()|+\\-*/]";
if (Pattern.compile(pattern).matcher(str).find()){
// 转换表达式
char[] data = str.toCharArray();
len=data.length;
// 计算结果
System.out.println(compute(data));
} else
System.out.println(-1);
scanner.close();
}
private static int compute(char[] data){
Stack<Integer> stack=new Stack<>();
char flag='+';
int num=0;
while (pos<len){
if(data[pos]=='{'||data[pos]=='('||data[pos]=='['){
pos++;
num=compute(data);
}
while(pos<len&&(data[pos]>='0'&&data[pos]<='9')){
num=num*10+(data[pos]-'0');
pos++;
}
switch (flag){
case '+':
stack.push(num);
break;
case '-':
stack.push(-num);
break;
case '*':
int temp = stack.pop();
stack.push(temp*num);
break;
case '/':
int temp1 = stack.pop();
stack.push(temp1/num);
break;
}
num=0;
if(pos<len){
flag=data[pos];
if(data[pos]=='}'||data[pos]==')'||data[pos]==']'){
pos++;
break;
}
pos++;
}
}
int res=0;
while (!stack.isEmpty()){
res+=stack.pop();
}
return res;
}
}
HJ56:iNOC产品部—完全数计算
完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。
例如:28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。
输入n,请输出n以内(含n)完全数的个数。计算范围, 0 < n <= 500000。本题输入含有多组样例。
输入描述:
输入一个数字n
输出描述:
输出不超过n的完全数的个数
示例1
输入
1000
7
100
输出
3
1
2
题解:
推导公式,大数学家欧拉曾推算出完全数的获得公式:
如果p是质数,且2^p-1也是质数,那么(2^p-1)X2^(p-1)便是一个完全数。
例如p=2,是一个质数,2^p-1=3也是质数,(2^p-1)X2^(p-1)=3X2=6,是完全数。
例如p=3,是一个质数,2^p-1=7也是质数,(2^p-1)X2^(p-1)=7X4=28,是完全数。
例如p=5,是一个质数,2^p-1=31也是质数,(2^p-1)X2^(p-1)=31X16=496是完全数。
当2^p-1是质数的时候,称其为梅森素数。
到2013年2月6日为止,人类只发现了48个梅森素数,较小的有3、7、31、127等
//方式1:普通思路 O(N^2)的时间复杂度
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int num=scanner.nextInt();
System.out.println(count(num));
}
scanner.close();
}
public static int count(int n){
int res=0;
int sum=0;
for(int i=2;i<=n;i++){
sum=0;
for(int j=1;j<=i/2;j++){
if(i%j==0)
sum+=j;
}
if(i==sum) res++;
}
return res;
}
}
//方式2:利用完全数的获得公式
import java.util.Scanner;
import java.lang.Math;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int num=scanner.nextInt();
int count=0;
for(int i=2;i<=Math.sqrt(num);i++){
long j=(long)Math.pow(2,i)-1;
if(isPrime(i)&&isPrime((int)j)){
long perfectNum=(long)Math.pow(2,i-1)*j;
if(perfectNum>0&&perfectNum<num)
count++;
}
}
System.out.println(count);
}
scanner.close();
}
private static boolean isPrime(int n){
for(int i=2;i<=Math.sqrt(n);i++){
if(n%i==0) return false;
}
return true;
}
}
HJ62:查找输入整数二进制中1的个数
输入一个正整数,计算它在二进制下的1的个数。
注意多组输入输出!!!!!!
输入描述:
输入一个整数
输出描述:
计算整数二进制中1的个数
示例1
输入
5
输出
2
说明
5的二进制表示是101,有2个1
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int num=scanner.nextInt();
int count=0;
while(num>0){
count++;
num&=(num-1);
}
System.out.println(count);
}
scanner.close();
}
}
HJ73:计算日期到天数转换
根据输入的日期,计算是这一年的第几天。。
测试用例有多组,注意循环输入
输入描述:
输入多行,每行空格分割,分别是年,月,日
输出描述:
成功:返回outDay输出计算后的第几天;
失败:返回-1
示例1
输入
2012 12 31
输出
366
//方式1:把每个月存入到数组中
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int year=scanner.nextInt();
int month=scanner.nextInt();
int day=scanner.nextInt();
if(year<1 || month<1 || month>12 || day<1 || day>31 || (month==2 && day>29)){
System.out.println(-1);
System.exit(0);
}
int[] days=new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
int res=0;
for(int i=0;i<month-1;i++){
res+=days[i];
}
if((year%4==0&&year%100!=0)||year%400==0)
res=res+day+1;
else
res=res+day;
System.out.println(res);
}
scanner.close();
}
}
//方式2:我自己的方式
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int year=scanner.nextInt();
int month=scanner.nextInt();
int day=scanner.nextInt();
if(year<1 || month<1 || month>12 || day<1 || day>31 || (month==2 && day>29)){
System.out.println(-1);
System.exit(0);
}
int res=0;
switch(month){
case 12:res+=30;
case 11:res+=31;
case 10:res+=30;
case 9:res+=31;
case 8:res+=31;
case 7:res+=30;
case 6:res+=31;
case 5:res+=30;
case 4:res+=31;
case 3:
if((year%4==0&&year%100!=0)||year%400==0) res+=29;
else res+=28;
case 2:res+=31;
case 1:res+=day;
}
System.out.println(res);
}
scanner.close();
}
}
HJ72:百钱买百鸡问题
公元前五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
详细描述:
接口说明
原型:
int GetResult(vector &list)
输入参数:
无
输出参数(指针指向的内存区域保证有效):
list :鸡翁、鸡母、鸡雏组合的列表
返回值:
-1 失败
0 成功
输入描述:
输入任何一个整数,即可运行程序。
输出描述:
示例1
输入
1
输出
0 25 75
4 18 78
8 11 81
12 4 84
题解:
考虑到鸡翁的范围在[0,20],鸡母的范围在[0,33],鸡雏则为100-X-Y,
再结合公式:5X+3Y+(100-X-Y)/3=100,则可以算出列表
HJ66:配置文件恢复
有6条配置命令,它们执行的结果分别是:
命 令 执 行
reset reset what
reset board board fault
board add where to add
board delete no board at all
reboot backplane impossible
backplane abort install first
he he unknown command
注意:he he不是命令。
为了简化输入,方便用户,以“最短唯一匹配原则”匹配:
1、若只输入一字串,则只匹配一个关键字的命令行。例如输入:r,根据该规则,匹配命令reset,执行结果为:reset what;输入:res,根据该规则,匹配命令reset,执行结果为:reset what;
2、若只输入一字串,但本条命令有两个关键字,则匹配失败。例如输入:reb,可以找到命令reboot backpalne,但是该命令有两个关键词,所有匹配失败,执行结果为:unknown command
3、若输入两字串,则先匹配第一关键字,如果有匹配但不唯一,继续匹配第二关键字,如果仍不唯一,匹配失败。例如输入:r b,找到匹配命令reset board 和 reboot backplane,执行结果为:unknown command。
4、若输入两字串,则先匹配第一关键字,如果有匹配但不唯一,继续匹配第二关键字,如果唯一,匹配成功。例如输入:b a,无法确定是命令board add还是backplane abort,匹配失败。
5、若输入两字串,第一关键字匹配成功,则匹配第二关键字,若无匹配,失败。例如输入:bo a,确定是命令board add,匹配成功。
6、若匹配失败,打印“unknown command”
输入描述:
多行字符串,每行字符串一条命令
输出描述:
执行结果,每条命令输出一行
示例1
输入
reset
reset board
board add
board delet
reboot backplane
backplane abort
输出
reset what
board fault
where to add
no board at all
impossible
install first
//字符串匹配:
//1.先看匹配串是一个字符还是两个字符,一个字符时,看匹配的字符是单字符还是双字符,单字符可以,双字符不行
//2.匹配串是两个字符时,看匹配了几个,只能匹配一个的话,算成功。大于一种,算不成功
//方式1:HashMap和HashSet的联合使用
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
Map<String, String> map=new HashMap<>();
map.put("reset","reset what");
map.put("reset board","board fault");
map.put("board add","where to add");
map.put("reboot backplane","impossible");
map.put("backplane abort","install first");
map.put("board delete","no board at all");
map.put("noMatch","unknown command");
Set<String[]> str=new HashSet<>();
for(String s:map.keySet()) {
str.add(s.split("\\ +"));
}
while(sc.hasNext()){
String[] arr=sc.nextLine().split("\\ +");
String res="noMatch";
int count=0;
for(String[] s:str) {
if(s.length==1&&arr.length==1&&s[0].startsWith(arr[0])){
res=s[0];
}
if(arr.length==2&&s.length==2){
if (s[0].startsWith(arr[0])&&s[1].startsWith(arr[1])) {
res=s[0]+" "+s[1];
count++;
}
}
}
System.out.println(count>1? "unknown command":map.get(res));
}
scanner.close();
}
}
//方式2:使用正则表达式进行匹配
import java.util.Scanner;
import java.util.TreeMap;
import java.util.Map;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
TreeMap<String,String> tm=new TreeMap<>();
tm.put("reset","reset what");
tm.put("reset board","board fault");
tm.put("board add","where to add");
tm.put("board delete","no board at all");
tm.put("reboot backplane","impossible");
tm.put("backplane abort","install first");
while(sc.hasNext()){
String cmd=sc.nextLine().trim();
String[] cmdSplit=cmd.split("\\ +");//按空格分割
String pipei="";
for(int i=0;i<cmdSplit.length-1;i++){
pipei=pipei.concat(cmdSplit[i]+"[a-z]*\\ +");//匹配关键字和空格
}
pipei=pipei.concat(cmdSplit[cmdSplit.length-1]+"[a-z]*");//匹配关键字,不带空格
String output="unknown command";
boolean flag=true;//是否匹配到多个
for(Map.Entry<String,String> cmdEntry : tm.entrySet()){
if(cmdEntry.getKey().matches(pipei)){
if(flag){
output=cmdEntry.getValue();
flag=false;
} else {
output="unknown command";
break;//匹配到多个,跳出循环
}
}
}
System.out.println(output);
}
scanner.close();
}
}
//方式3:我的笨办法
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
String[] str=scanner.nextLine().trim().split(" ");
if(str.length==1){
if("reset".startsWith(str[0]))
System.out.println("reset what");
else
System.out.println("unknown command");
}else if(str.length==2){
if(("reset".startsWith(str[0])&&"board".startsWith(str[1]))&&
(!"reboot".startsWith(str[0])||!"backplane".startsWith(str[1])))
System.out.println("board fault");
else if((!"reset".startsWith(str[0])||!"board".startsWith(str[1]))&&
("reboot".startsWith(str[0])&&"backplane".startsWith(str[1])))
System.out.println("impossible");
else if(("board".startsWith(str[0])&&"add".startsWith(str[1]))&&
(!"backplane".startsWith(str[0])||!"abort".startsWith(str[1])))
System.out.println("where to add");
else if((!"board".startsWith(str[0])||!"add".startsWith(str[1]))&&
("backplane".startsWith(str[0])&&"abort".startsWith(str[1])))
System.out.println("install first");
else if("board".startsWith(str[0])&&"delete".startsWith(str[1]))
System.out.println("no board at all");
else
System.out.println("unknown command");
}else{
System.out.println("unknown command");
}
}
scanner.close();
}
}
HJ61:放苹果
把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
数据范围:0<=m<=10,1<=n<=10。本题含有多组样例输入。
输入描述:
输入两个int整数
输出描述:
输出结果,int型
示例1
输入
7 3
输出
8
设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论:
一、当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。
即if(n>m) f(m,n) = f(m,m)
二、当n<=m:不同的放法可以分成两类:
1、有至少一个盘子空着,即相当于f(m,n) = f(m,n-1);
2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n).
而总的放苹果的放法数目等于两者的和,即 f(m,n)=f(m,n-1)+f(m-n,n)
三、递归出口条件说明:
当n=1时,所有苹果都必须放在一个盘子里,所以返回1;
当m=0时,没有苹果可放时,定义为1种放法;
四、递归的两条路:
第一条n会逐渐减少,终会到达出口n==1;( f(m,n-1) )
第二条m会逐渐减少,因为n>m时,我们会return f(m,m) 所以终会到达出口m==0.( f(m-n,n) )
//方式1:递归
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int m=scanner.nextInt();
int n=scanner.nextInt();
System.out.println(f(m,n));
}
scanner.close();
}
private static int f(int m,int n){
if(m==0||n==1){
return 1;
}else if(n>m){
return f(m,m);
}else{
return f(m,n-1)+f(m-n,n);
}
}
}
HJ108:求最小公倍数
正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。
输入描述:
输入两个正整数A和B。
输出描述:
输出A和B的最小公倍数。
示例1
输入
5 7
输出
35
题解:
求最小公倍数
a,b的最大公约数为gcd(a,b),最小公倍数的公式为:
计算a = 1071和b = 462的最大公约数的过程如下:
从1071中不断减去462直到小于462(可以减2次,即商q0 = 2),余数是147:
1071 = 2 × 462 + 147.
然后从462中不断减去147直到小于147(可以减3次,即q1 = 3),余数是21:
462 = 3 × 147 + 21.
再从147中不断减去21直到小于21(可以减7次,即q2 = 7),没有余数:
147 = 7 × 21 + 0.
此时,余数是0,所以1071和462的最大公约数是21。
//方式1:
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int A=scanner.nextInt();
int B=scanner.nextInt();
int res=A*B;
if(A<B){//A是较大值
int temp = B;
B = A;
A =temp;
}
while(B!=0){//最大公约数是A
int r = A%B;
A = B;
B = r;
}//跳出循环时说明B=0
System.out.println(res/A);
scanner.close();
}
}
//方式2:
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int A=scanner.nextInt();
int B=scanner.nextInt();
System.out.println(A*B/gcd(A,B));
scanner.close();
}
private static int gcd(int a,int b){
if(a<b)//确保a大b小
gcd(b,a);
if(b==0)
return a;
else
return gcd(b,a%b);
}
}
HJ12:字符串反转
接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)
输入描述:
输入一行,为一个只包含小写字母的字符串。
输出描述:
输出该字符串反转后的字符串。
示例1
输入
abcd
输出
dcba
//方式1:使用StringBuilder
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String str=scanner.nextLine().trim();
StringBuilder builder=new StringBuilder();
for(int i=str.length()-1;i>=0;i--){
builder.append(str.charAt(i));
}
System.out.println(builder.toString());
scanner.close();
}
}
//方式2:直接使用API,new StringBuilder(String str)
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String str=scanner.nextLine().trim();
System.out.println(new StringBuilder(str).reverse());
scanner.close();
}
}
HJ83:二维数组操作
题目详情的链接:https://www.nowcoder.com/practice/2f8c17bec47e416897ce4b9aa560b7f4?tpId=37&tqId=21306&rp=1&ru=%2Fta%2Fhuawei&qru=%2Fta%2Fhuawei%2Fquestion-ranking&tab=answerKey
输入描述:
输入数据按下列顺序输入:
1 表格的行列值
2 要交换的两个单元格的行列值
3 输入要插入的行的数值
4 输入要插入的列的数值
5 输入要查询的单元格的坐标
输出描述:
输出按下列顺序输出:
1 初始化表格是否成功,若成功则返回0, 否则返回-1
2 输出交换单元格是否成功
3 输出插入行是否成功
4 输出插入列是否成功
5 输出查询单元格数据是否成功
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int row=scanner.nextInt();
int col=scanner.nextInt();
if(!judge(10,10,row,col)){//if(row>9||row<1||col>9||col<1){
System.out.println(-1);
}else{
System.out.println(0);
int[][] arr=new int[row][col];
int frow=scanner.nextInt();
int fcol=scanner.nextInt();
int srow=scanner.nextInt();
int scol=scanner.nextInt();
if(judge(row,col,frow,fcol)&&judge(row,col,srow,scol))
System.out.println(0);
else
System.out.println(-1);
int insertRow=scanner.nextInt();
if(row+1<=9&&judge(row,col,insertRow,0))
System.out.println(0);
else
System.out.println(-1);
int insertCol=scanner.nextInt();
if(col+1<=9&&judge(row,col,0,insertCol))
System.out.println(0);
else
System.out.println(-1);
int findRow=scanner.nextInt();
int findCol=scanner.nextInt();
if(judge(row,col,findRow,findCol))
System.out.println(0);
else
System.out.println(-1);
}
}
scanner.close();
}
private static boolean judge(int row,int col,int testRow,int testCol){
if(testRow<=row-1&&testRow>=0&&testCol<=col-1&&testCol>=0)
return true;
else
return false;
}
}
HJ84:统计大写字母个数
找出给定字符串中大写字符(即’A’-‘Z’)的个数。
输入描述:
本题含有多组样例输入
对于每组样例,输入一行,代表待统计的字符串
输出描述:
对于每组样例,输出一个整数,代表字符串中大写字母的个数
示例1
输入
add123#$%#%#O
150175017(&^%&$vabovbao
输出
1
0
//方法1:replaceAll("[^A-Z]",""),利用正则表达式把非大写字母全部清除,剩下的字母个数就是大写字母的个数
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
String inStr=scanner.nextLine().trim().replaceAll("[^A-Z]","");
System.out.println(inStr.length());
}
scanner.close();
}
}
//笨蛋办法一:
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
String inStr=scanner.nextLine().trim();
int count=0;
for(int i=0;i<inStr.length();i++){
if(Character.isUpperCase(inStr.charAt(i)))
count++;
}
System.out.println(count);
}
scanner.close();
}
}
//笨蛋办法二:
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
String inStr=scanner.nextLine().trim();
int count=0;
for(int i=0;i<inStr.length();i++){
if(inStr.charAt(i)>='A'&&inStr.charAt(i)<='Z')
count++;
}
System.out.println(count);
}
scanner.close();
}
}
//笨蛋办法三:
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String testStr="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
while(scanner.hasNext()){
String inStr=scanner.nextLine().trim();
int count=0;
for(int i=0;i<inStr.length();i++){
if(testStr.contains(String.valueOf(inStr.charAt(i))))
count++;
}
System.out.println(count);
}
scanner.close();
}
}
HJ75:公共字串计算
给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。
注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。
输入描述:
输入两个只包含小写字母的字符串
输出描述:
输出一个整数,代表最大公共子串的长度
示例1
输入
asdfas
werasdfaswer
输出
6
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
String str1=scanner.next().trim();
String str2=scanner.next().trim();
String maxStr=(str1.length()>str2.length())?str1:str2;
String minStr=(str1.length()<str2.length())?str1:str2;
int minLen=minStr.length();
for(int i=0;i<minLen;i++){
for(int x=0,y=minLen-i;y<=minLen;x++,y++){
String subStr=minStr.substring(x,y);
if(maxStr.contains(subStr)){
System.out.println(subStr.length());
return;//System.exit(0);
}
}
}
}
scanner.close();
}
}
HJ76:尼科彻斯定理
验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。
例如:
1^3=1
2^3=3+5
3^3=7+9+11
4^3=13+15+17+19
输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。
本题含有多组输入数据。
输入描述:
输入一个int整数
输出描述:
输出分解后的string
示例1
输入
6
输出
31+33+35+37+39+41
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int m=scanner.nextInt();
int x=m*m-m+1;//先找到拆解成数列和的首项
StringBuilder builder=new StringBuilder();
for(int i=1;i<m;i++){
builder.append(x+"+");
x+=2;
}
builder.append(x);
System.out.println(builder.toString());
}
scanner.close();
}
}
HJ86:求最大连续bit数
求一个byte数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1
本题含有多组样例输入。
输入描述:
输入一个byte数字
输出描述:
输出转成二进制之后连续1的个数
示例1
输入
3
5
输出
2
1
说明
3的二进制表示是11,最多有2个连续的1。
5的二进制表示是101,最多只有1个连续的1。
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int m=scanner.nextInt();
int maxCount=0;
int count=0;
while(m>0){
if((m&1)==1){//此处的优化就是每统计到一个1,则更新最大连续1的个数
count++;
maxCount=(maxCount>count)?maxCount:count;
}else{//每统计到0,则重新统计连续1的个数
count=0;
}
m>>>=1;//使用无符号右移>>>,无论正数负数都是在左侧补0
}
System.out.println(maxCount);
}
scanner.close();
}
}
//提示:将短的那个串进行长度依次递减的子串与较长的串比较。
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
String str1=scanner.next().trim();
String str2=scanner.next().trim();
String maxStr=(str1.length()>str2.length())?str1:str2;
String minStr=(str1.length()<str2.length())?str1:str2;
int minLen=minStr.length();
for(int i=0;i<minLen;i++){//每轮少一个字符
for(int x=0,y=minLen-i;y<=minLen;x++,y++){//确定截取的字符串的索引,左闭右开
String subStr=minStr.substring(x,y);
if(maxStr.contains(subStr)){
System.out.println(subStr.length());
return;//System.exit(0);
}
}
}
}
scanner.close();
}
}
HJ85:字符串运用-密码截取(最长回文字符串)
给定一个仅包含小写字母的字符串,求它的最长回文子串的长度。
所谓回文串,指左右对称的字符串。
所谓子串,指一个字符串删掉其部分前缀和后缀(也可以不删)的字符串
(注意:记得加上while处理多个测试用例)
输入描述:
输入一个仅包含小写字母的字符串
输出描述:
返回最长回文子串的长度
示例1
输入
cdabbacc
输出
4
说明
abba为最长的回文子串
题解
动态规划:
1.dp[i]表示以第i位字符结尾的最大回文串的长度
2.i-dp[i-1]-1>=0的条件是非常有必要的,
因为可能存在 abbcbd的这种情况;如果设置为i-dp[i-1]-1==0,则会导致bcb不会被计算成回文字符串
3.分三种情况组成回文
a.如果是中间相隔了一串回文字符的两个字符相等,则回文字符长度加2(中间的可能是单独的字符,也可能是一串回文字符串,但他们都是回文字符,即:如果是回文(abcba),则去除头尾(bcb)后也是回文)
b.如果相邻的两个字符相同,则回文字符长度加1
c.单独的字符形成的回文字符长度为1
4.dp[i-1]代表了从索引i到索引i-dp[i-1]-1之间的回文字符串的长度(前提是这两个索引处的字符相等)
//方式1:时间复杂度为O(N)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
while(in.hasNext()){
String str=in.next();
int[] dp=new int[str.length()];//dp[i]表示以第i位字符结尾的最大回文串的长度
dp[0]=1;//只有一个字符的时候最长回文为1
int max=0;
for(int i=1;i<str.length();i++){
if(i-dp[i-1]-1>=0&&str.charAt(i)==str.charAt(i-dp[i-1]-1)){
dp[i]=dp[i-1]+2;//如果是中间相隔了一串回文字符的两个字符相等,则回文字符长度加2
}else if(str.charAt(i)==str.charAt(i-1)){
dp[i]=dp[i-1]+1;//如果相邻的两个字符相同,则回文字符长度加1
}else {
dp[i]=1;//单独的字符形成的回文字符长度为1
}
max=Math.max(max,dp[i]);//更新以当前字符结尾的最长回文字符串
}
System.out.println(max);
}
in.close();
}
}
HJ74:参数解析
在命令行输入如下命令:
xcopy /s c:\ d:\,
各个参数如下:
参数1:命令字xcopy
参数2:字符串/s
参数3:字符串c:\
参数4: 字符串d:\
请编写一个参数解析程序,实现将命令行各个参数解析出来。
解析规则:
1.参数分隔符为空格
2.对于用“”包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy /s “C:\program files” “d:\”时,参数仍然是4个,第3个参数应该是字符串C:\program files,而不是C:\program,注意输出参数时,需要将“”去掉,引号不存在嵌套情况。
3.参数不定长
4.输入由用例保证,不会出现不符合要求的输入
输入描述:
输入一行字符串,可以有空格
输出描述:
输出参数个数,分解后的参数,每个参数都独占一行
示例1
输入
xcopy /s c:\ d:\
输出
4
xcopy
/s
c:\
d:\
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String str=scanner.nextLine().trim();
StringBuilder builder=new StringBuilder();
int count=1;//因为最后一个字符串不能让count++
int flag=0;
for(int i=0;i<str.length();i++){
if(str.charAt(i)=='\"'){
flag++;
}else if(str.charAt(i)!=' '){
builder.append(str.charAt(i));
}else if(str.charAt(i)==' '&&flag%2!=0){
builder.append(str.charAt(i));
}else if(str.charAt(i)==' '&&flag%2==0){
builder.append("\n");
count++;
}
}
System.out.println(count);
System.out.println(builder.toString());
scanner.close();
}
}
HJ87:密码强度等级
密码按如下规则进行计分,并根据不同的得分为密码进行安全等级划分。
一、密码长度:
5 分: 小于等于4 个字符
10 分: 5 到7 字符
25 分: 大于等于8 个字符
二、字母:
0 分: 没有字母
10 分: 全都是小(大)写字母
20 分: 大小写混合字母
三、数字:
0 分: 没有数字
10 分: 1 个数字
20 分: 大于1 个数字
四、符号:
0 分: 没有符号
10 分: 1 个符号
25 分: 大于1 个符号
五、奖励:
2 分: 字母和数字
3 分: 字母、数字和符号
5 分: 大小写字母、数字和符号
最后的评分标准: 对应输出为
= 90: 非常安全 VERY_SECURE
= 80: 安全(Secure) SECURE,
= 70: 非常强 VERY_STRONG,
= 60: 强(Strong) STRONG,
= 50: 一般(Average) AVERAGE,
= 25: 弱(Weak) WEAK,
= 0: 非常弱 VERY_WEAK,
请根据输入的密码字符串,进行安全评定。
注:
字母:a-z, A-Z
数字:0-9
符号包含如下: (ASCII码表可以在UltraEdit的菜单view->ASCII Table查看)
!”#$%&’()+,-./ (ASCII码:x21~0x2F)
:;<=>?@ (ASCII码:x3A~0x40)
[]^_` (ASCII码:x5B~0x60)
{|}~ (ASCII码:x7B~0x7E)
输入描述:
本题含有多组输入样例。
每组样例输入一个string的密码
输出描述:
每组样例输出密码等级
示例1
*输入
38$@NoNoNo
123
输出
VERY_SECURE
WEAK
说明
第一组样例密码强度为95分。
第二组样例密码强度为25分。
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
String str=scanner.next();
int score=0;
int len=str.length();
if(len>=8){//字符长度
score+=25;
} else if(len>=5){
score+=10;
} else{
score+=5;
}
int numCount=0,symbolCount=0;
boolean numFlag=false,symbolFlag=false,upperFlag=false,lowerFlag=false;
for(int i=0;i<str.length();i++){
char ch=str.charAt(i);
if(ch>=0x21&&ch<=0x2F||ch>=0x3A&&ch<=0x40||ch>=0x5B&&ch<=0x60||ch>=0x7B&&ch<=0x7B){
symbolCount++;
symbolFlag=true;
}
if(ch>='0'&&ch<='9'){
numCount++;
numFlag=true;
}
if(ch>='a'&&ch<='z'){
lowerFlag=true;
}
if(ch>='A'&&ch<='Z'){
upperFlag=true;
}
}
if(upperFlag&&lowerFlag){//字母大小写
score+=20;
}else if(upperFlag||lowerFlag){
score+=10;
}
if(numCount>1){//数字个数
score+=20;
}else if(numCount==1){
score+=10;
}
if(symbolCount>1){//符号个数
score+=25;
}else if(symbolCount==1){
score+=10;
}
if(symbolFlag&&numFlag&&lowerFlag&&upperFlag){//奖励加分
score+=5;
}else if(symbolFlag&&numFlag&&(lowerFlag||upperFlag)){
score+=3;
}else if(numFlag&&(lowerFlag||upperFlag)){
score+=2;
}
print(score);
}
scanner.close();
}
private static void print(int score){
if(score>=90){
System.out.println("VERY_SECURE");
}else if(score>=80){
System.out.println("SECURE");
}else if(score>=70){
System.out.println("VERY_STRONG");
}else if(score>=60){
System.out.println("STRONG");
}else if(score>=50){
System.out.println("AVERAGE");
}else if(score>=25){
System.out.println("WEAK");
}else{
System.out.println("VERY_WEAK");
}
}
}
HJ100:等差数列
功能:等差数列 2,5,8,11,14。。。。
输入:正整数N >0
输出:求等差数列前N项和
本题为多组输入,请使用while(cin>>)等形式读取数据
输入描述:
输入一个正整数。
输出描述:
输出一个相加后的整数。
示例1
输入
2
输出
7
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int n=scanner.nextInt();
System.out.println((3*n*n+n)/2);
}
scanner.close();
}
}
HJ91:走方格的方案数
请计算nm的棋盘格子(n为横向的格子数,m为竖向的格子数)沿着各自边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路,即:只能往右和往下走,不能往左和往上走。
本题含有多组样例输入。
输入描述:
每组样例输入两个正整数n和m,用空格隔开。(1≤n,m≤8)
输出描述:
每组样例输出一行结果
示例1
输入
2 2
1 2
*输出
6
3
//方式1:用递归来做,将右下角看做原点(0, 0),左上角看做坐标(m, n)
从(m, n)—>(0, 0)就分两步走:
往右走一步:f(m, n - 1)—>(0, 0) 加上下走一步:f(m - 1, n)—>(0, 0)
注意:但凡是触碰到边界,也就是说f(x, 0)或者f(0,x)都只有一条直路可走了(也可以看做是递归的终止条件)
f(m, n) = f(m, n - 1) + f(m - 1, n)
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int row=scanner.nextInt();
int col=scanner.nextInt();
System.out.println(dsf(row,col));
}
scanner.close();
}
private static int dsf(int row,int col){
if(row==0||col==0)
return 1;
return dsf(row-1,col)+dsf(row,col-1);
}
}
//方式2:用递归来做,将左上角看做原点(0, 0),右下角看做坐标(m, n)
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int row=scanner.nextInt();
int col=scanner.nextInt();
int[][] arr=new int[row+1][col+1];
System.out.println(dsf(arr,row+1,col+1,0,0));
}
scanner.close();
}
private static int dsf(int[][] arr,int row,int col,int i,int j){
//凡是触碰到边界,就是说f(x, 0)或者f(0,x),都只有一条直路可走了,就是走到目的地
//(也可以看做是递归的终止条件)
if(i==row-1||j==col-1)
return 1;
return dsf(arr,row,col,i+1,j)+dsf(arr,row,col,i,j+1);
}
}
//方式3:动态规划
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int row=scanner.nextInt();
int col=scanner.nextInt();
System.out.println(dsf(row,col));
}
scanner.close();
}
private static int dsf(int row,int col){
int[][] dp=new int[row+1][col+1];
for(int i=0;i<=row;i++){
for(int j=0;j<=col;j++){
if(i==0||j==0){
dp[i][j]=1;
}else{
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
}
return dp[row][col];
}
}
//方式4:排列组合的公式
运用动态规划,不难推导,输入整数对(m,n),其返回值F(m,n)应该是m阶等差数列的第n项。m与n的作用完全对称,F(m,n)同样也是n阶等差数列的第m项。
而事实上,F(m,n)构成了杨辉三角,故利用杨辉三角通项公式可知:F(m,n) = (m+n)!/m!/n!
所以,也可直接使用阶乘函数进行运算。
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int row=scanner.nextInt();
int col=scanner.nextInt();
System.out.println(factorial(row+col)/factorial(row)/factorial(col));
}
scanner.close();
}
private static int factorial(int n){
if(n==1)
return 1;
else
return n*factorial(n-1);
}
}
中等
HJ10:字符个数统计
编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次
例如,对于字符串abaca而言,有a、b、c三种不同的字符,因此输出3。
输入描述:
输入一行没有空格的字符串。
输出描述:
输出范围在(0~127)字符的个数。
示例1
输入
abc
输出
3
构造器:
BitSet(int nbits):它的初始大小足以显式表示索引范围在 0 到 nbits-1 的位。所有的位初始均为 false。
方法:
boolean get(int bitIndex) 返回指定索引处的位值。
void set(int bitIndex) 将指定索引处的位设置为 true。
public int cardinality() 返回此 BitSet 中设置为 true 的位数。
//方式1:使用128长度的boolean数组来进行判断,boolean[] res=new boolean[128]
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String str=scanner.nextLine();
boolean[] res=new boolean[128];
int count=0;
for(int i=0;i<str.length();i++){
res[str.charAt(i)]=true;
}
for(int i=0;i<res.length;i++){
if(res[i]!=false){
count++;
}
}
System.out.println(count);
scanner.close();
}
}
//方式2:使用HashSet的天然去重性质
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String str=scanner.nextLine();
HashSet<Character> set=new HashSet<>();
for(int i=0;i<str.length();i++){
set.add(str.charAt(i));
}
System.out.println(set.size());
scanner.close();
}
}
//方式3:Java中可使用位图统计,凡是涉及到去重统计都可以用位图实现。
//因为每一个不同的数据只需要用二进制的一位存储即可,大大减小了统计所使用的存储空间
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line = scanner.next();
BitSet bitSet = new BitSet(128); //总共有128个字符。只需要用128位
for (char c : line.toCharArray()) {
if (!bitSet.get(c)) {//判断字符c是否已出现,获取这个位为false则是没出现过
bitSet.set(c);//未出现就设置为已出现,设为true
}
}
System.out.println(bitSet.cardinality());//统计有多少字符已出现过
}
}
HJ34:图片整理
Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过C语言解决。
本题含有多组样例输入。
输入描述:
Lily使用的图片包括”A”到”Z”、”a”到”z”、”0”到”9”。输入字母或数字个数不超过1024。
输出描述:
Lily的所有图片按照从小到大的顺序输出
示例1
输入
Ihave1nose2hands10fingers
输出
0112Iaadeeefghhinnnorsssv
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
char[] arr=scanner.nextLine().trim().toCharArray();
Arrays.sort(arr);
System.out.println(String.valueOf(arr));//或者 new String(arr)
}
scanner.close();
}
}