2.1 抽纸片(java)
【问题描述】你的朋友提议玩一个游戏:将写有数字的的n纸片放入口袋中,你可以从口袋中抽取三次纸片,每次记下纸片上的数字后都将其放回到口袋中,如果这三个数字的和是m,就是你赢,否则就是你朋友赢。请你编写一个程序,判断当纸片上所写的数字是k1,k2,…,kn时是否存在抽取三次之和为m的方案。
【输入形式】输入的第一行为一个正整数 n 表示口袋中纸片数目(int类型)第二行为一个正整数表示三个数字的和 第三行为n个整数表示每个纸片上的数字(int类型)
【输出形式】如果存在符合要求的方案,输出Y,否则,输出N。
【样例输入】
3
10
2 3 5
【样例输出】
Y
【代码】
import java.util.Scanner;
import java.util.Arrays;
public class A1 {
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
int n;
int num;
int sum=0;
int m=0;
n=scan.nextInt();//纸片数目
num=scan.nextInt();//数字之和
int[] a=new int[n];
for(int i=0;i<n;i++)
{
a[i]=scan.nextInt();//纸片上的数字
}
scan.close();
loop1:for(int i=0;i<n;i++)//最简单的思路:三重for循环
{
for(int j=i+1;j<n;j++)
{
for(int k=j+1;k<n;k++)
{
sum=a[i]+a[j]+a[k];//计算三张纸片之和
if(sum==num)//若相等
{
System.out.println("Y");
m=1;//用m标记
break loop1;
}
}
}
}
if(m==0) System.out.println("N");
}
}
【知识点】
1、关于Java中break和continue跳出指定循环
break和continue后不加任何循环名则默认跳出其所在的循环;
在其后加指定循环名(eg.loop1、loop2),则可以跳出该指定循环。
形式:
loop1:for(int i=0;i<n;i++)
{
loop2:for(int j=i+1;j<n;j++)
{
if(...)
{
break loop1;
}
else
{
continue loop2;
}
}
}
2.2 导弹防御系统(Java)
【问题描述】某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹。拦截来袭导弹时,必须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。
【输入形式】每组输入有两行,第一行,输入雷达捕捉到的敌国导弹的数量k(k<=25),第二行,输入k个正整数,表示k枚导弹的高度,按来袭导弹的袭击时间顺序给出,以空格分隔。
【输出形式】每组输出只有一行,包含一个整数,表示最多能拦截多少枚导弹。
【样例输入】
8
300 207 155 300 299 170 158 65
【样例输出】 6
【代码】
package a2;
import java.util.Scanner;
import java.util.Arrays;
public class A2 {
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
int n=0;
n=scan.nextInt();
int[] a=new int[26];
int[] b=new int[26];
int max=0;
for(int i=0;i<n;i++)
{
a[i]=scan.nextInt();
b[i]=1;
}
scan.close();
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(a[i]<=a[j]&&b[j]+1>b[i])//j在i前面,且j比i高,则可以考虑是否捕捉i,若j处捕获数+1大于i处,则更新b[i]
{
b[i]=b[j]+1;
}
}
if(b[i]>max) max=b[i];//更新max
}
System.out.print(max);
}
}
2.3 选美比赛(Java)
【问题描述】在选美大奖赛的半决赛现场,有n名选手(2<n<100)参加比赛。比赛结束时,要在现场按照选手的出场顺序宣布最后名次,获得相同分数的选手具有相同的名次,名次连续编号,不用考虑同名次的选手人数。如:
【输入形式】选手数量:7 选手得分:5;3;4;7;3;5;6
【输出形式】选手的排名:3 5 4 1 5 3 2
【样例输入】7 5 3 4 7 3 5 6
【样例输出】3 5 4 1 5 3 2
【代码】
import java.util.Scanner;
import java.util.Arrays;
public class A3 {
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
int n=0;
n=scan.nextInt();//选手数量
int[] a=new int[n];//选手得分
int[] b=new int[n];//用于处理重复的得分
int[] c=new int[n];//表示选手排名(初始化为0)
for(int i=0;i<n;i++)
{
a[i]=scan.nextInt();//获取选手得分
b[i]=a[i];//复制
}
scan.close();
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(b[i]==b[j])//若两得分相等,则将其中一个得分归0
{
b[j]=0;
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(a[i]<b[j])//遍历比较
{
c[i]++;//存在比其得分高的,则排名加1
}
}
}
for(int i=0;i<n;i++)
{
System.out.print(c[i]+1+" ");//初始化为0,输出时注意加1
}
}
}
2.4 子网判断(Java)
【问题描述】 子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。子网掩码与 IP 地址结构相同,是32 位二进制数,其中网络号部分全为 “1” 和主机号部分全为 “0” 。利用子网掩码可以判断两台主机是否中同一子网中。若两台主机的IP 地址分别与它们的子网掩码相 “与” 后的结果相同,则说明这两台主机在同一子网中。示例:IP 地址192.168.0.1子网掩码255.255.255.0转化为二进制进行运算:IP地址11010000.10101000.00000000.00000001子网掩码11111111.11111111.11111111.00000000 AND运算11010000.10101000.00000000.00000000转化为十进制后为:192.168.0.0 IP 地址 192.168.0.254子网掩码 255.255.255.0转化为二进制进行运算:IP地址11010000.10101000.00000000.11111110子网掩码11111111.11111111.11111111.00000000 AND运算11010000.10101000.00000000.00000000 转化为十进制后为:192.168.0.0 通过以上对两台计算机IP 地址与子网掩码的 AND 运算后,我们可以看到它运算结果是一样的。均为192.168.0.0,所以这二台计算机可视为是同一子网络。
【输入形式】输入子网掩码、两个地址
【输出形式】得到计算结果,如不在同一子网,则输出0
【样例输入】
255.255.255.0
192.168.224.254
192.168.10.4
【样例输出】
0
【样例输入】
255.255.255.0
192.168.0.254
192.168.0.1
【样例输出】
1
【代码】
package a2;
import java.util.Scanner;
import java.util.Arrays;
public class A4 {
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
String n;
int [][]a=new int[3][4];//分别用于存储子网掩码和两个地址
//都由4个整型数字表示
String[] b=new String[3];//转化为二进制字符串后
b[0]="";
b[1]="";
b[2]="";
String[] c=new String[2];//分别AND运算后
c[0]="";
c[1]="";
for(int i=0;i<3;i++)
{
n=scan.next();
int len=n.length();
int num1=0;
for(int j=0;j<3;j++)
{
int num2=n.indexOf('.',num1);//从num1开始找“.”的索引 [注意从num1开始寻找]
String str1=n.substring(num1,num2);//截取数字
num1=num2+1;
a[i][j]= Integer.valueOf(str1);//字符串转化为整数
String str3=Integer.toBinaryString(a[i][j]);//将十进制整数转化为二进制形式(字符串)
int num3=Integer.valueOf(str3);//将字符串转化为整数
b[i]+=String.format("%08d", num3);
// 0 代表前面补充0
// 8代表长度为8
// d 代表参数为正数型
}
String str2=n.substring(num1,len);//获取最后.到结束的字符串
a[i][3]= Integer.valueOf(str2);
String str3=Integer.toBinaryString(a[i][3]);
int num3=Integer.valueOf(str3);
b[i]+=String.format("%08d", num3);
}
scan.close();
for(int i=0;i<32;i++)
{
if(b[0].charAt(i)=='1'&&b[1].charAt(i)=='1')//都为1,则为1
{
c[0]+='1';
}
else c[0]+='0';
if(b[0].charAt(i)=='1'&&b[2].charAt(i)=='1')
{
c[1]+='1';
}
else c[1]+='0';
}
if(c[0].contentEquals(c[1])) System.out.print("1");//若两字符串相等,则输出1
else System.out.print("0");
}
}
【知识点】
1、二维数组的声明
1.1 三种初始化方法
1)使用大括号直接赋值,适合已经确定知道数组元素的情况
int [][]a={{1,2,3,4}, {2,3,4,5}, {4,5,6,7}};//三行四列
2)给定二维数组的大小
int [][]a=new int[3][4];//三行四列
String [][]a=new String[3][4];
3)数组第二维的长度可变化,未改变
int [][]a=new int[3][];//三行四列
String [][]a=new String[3][];
1.2 对比一维数组:
int[] c=new int[2];
String[] c=new String[2];
2、字符串的操作
int num2=n.indexOf('.',num1);//从num1开始找“.”的索引
String str1=n.substring(num1,num2);//截取数字
a[i][j]= Integer.valueOf(str1);//字符串转化为整数
b[0].charAt(i)//获取字符串b[0]的第i个字符
更多关于字符串的操作:
https://blog.csdn.net/sjq__python_web/article/details/80099454
3、十进制数转化为二进制数
String str3=Integer.toBinaryString(a[i][j]);
//将十进制整数(a[i][j]转化为二进制形式(字符串str3)
String str=Integer.toBinaryString(int i)
//转化的二进制以字符串的形式返回
关于十进制转化二进制的思路:
https://blog.csdn.net/weixin_42370303/article/details/80562611
4、数字转字符串前补0
String str=String.format("%08d", int num);
// 0 代表前面补充0
// 8代表长度为8
// d 代表参数为正数型
5、判断字符串是否相等
[注意]:==比较引用(只能确定两个字符串是否放置在同一个位置上),equals 比较值。
本题中通过样例发现若采用“==”来比较字符串是否相等,会出现错误,采用equals得正确结果。
若要比较字符串内容是否相同,则最好采取equals:
a.equals(b);//若字符串a与字符串b内容相同,返回true,否则返回false。
若要忽略大小写:使用equalsIgnoreCase()方法。
2.5 水瓶换水(java)
【问题描述】有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
【输入形式】输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=100),表示小张手上的空汽水瓶数。n=0表示输入结束,你的程序不应当处理这一行。
【输出形式】对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。
【样例输入】 3 10 81 0
【样例输出】 1 5 40
【思路】
此题要点在于剩两个空汽水瓶时,可让老板借一瓶,此时最多可以喝的汽水瓶数加一。通过使用 “\” ,"%" 在计算中的特点处理该题。
【代码】
import java.util.Scanner;
public class A5 {
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
while(true)
{
int sum=0;//总可换汽水瓶数
int chu=0;//每次可换汽水瓶数
int n=0;//空汽水瓶个数
n=scan.nextInt();
if(n==0) break;//n=0表示输入结束
while(n>=3)//小于3时,不能在换汽水
{
chu=n/3;//获取整除后的数
sum+=chu;
n=n%3;//获取换了汽水后的空汽水瓶数
n+=chu;//喝掉汽水后的空汽水瓶数
}
if(n==2) System.out.print(sum+1+" ");//当剩两个空汽水瓶时,可向店长借一瓶,能多喝一瓶,则输出sum+1
else if(n==1) System.out.print(sum+" ");
}
scan.close();
}
}
2.6密码检查(JAVA)
【问题描述】
开发一个密码检查软件,密码要求:
- 长度超过8位
- 包括大小写字母.数字.其它符号,以上四种至少三种
- 不能有相同长度大于或等于2的子串重复
【输入形式】
一组或多组长度超过2的子符串。每组占一行
【输出形式】
如果符合要求输出:OK,否则输出NG
【样例输入】
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000
【样例输出】
OK
NG
NG
OK
【代码】
import java.util.Scanner;
import java.util.Arrays;
public class A6 {
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
while(scan.hasNext())
{
String x;
x=scan.next();//输入的字符串
//System.out.println(x);
int m=0;//字符串长度
m=x.length();
int kin=0;//表示没有kin种符号
int[] kind=new int[4];//分别表示四种字符(初始化为0)
for(int i=0;i<m;i++)
{
if(x.charAt(i)>='0'&&x.charAt(i)<='9')//为数字
{
kind[0]++;
}
else if(x.charAt(i)>='a'&&x.charAt(i)<='z')//为小写字母
{
kind[1]++;
}
else if(x.charAt(i)>='A'&&x.charAt(i)<='Z')//为大写字母
{
kind[2]++;
}
else kind[3]++;//其他符号
}
for(int i=0;i<4;i++)
{
if(kind[i]==0)
kin++;//表示没有几种符号
}
int flag=0;
loop1:for(int i=0;i<m-1;i++)//双重for循环遍历
{
for(int j=i+1;j<m-1;j++)
{
if(x.charAt(i)==x.charAt(j)&&x.charAt(i+1)==x.charAt(j+1)&&i+1!=j)
//判断是否有>=2长度的子串重复,i+1!=j:避免000误判的情况
{
flag=1;//表示有子串重复
break loop1;//跳出循环
}
}
}
if(kin>1||m<=8||flag==1) //不满足题目要求任意条件,输出NG
{
System.out.println("NG");
}
else System.out.println("OK");
}
scan.close();
}
}
【知识点】
1、关于Scanner的hasNext()
循环时候如何使用hasNext()方法:遇到hasNext()时,Scanner也会阻塞,等待你输入,等你输入后返回true。
while(scan.hasNext())
{
......
}
关于Scanner更多用法:
https://blog.csdn.net/weixin_41262453/article/details/88815173
2、关于字符串的操作
1)获取长度:int len=str.length(); len为字符串str的长度;
2)获取指定索引位置的字符:str.charAt(i);获取字符串str第i个字符;
关于字符串的更多操作:
https://www.cnblogs.com/StarZhai/p/10577880.html
3、关于Java中break和continue跳出指定循环
break和continue后不加任何循环名则默认跳出其所在的循环;
在其后加指定循环名(eg.loop1、loop2),则可以跳出该指定循环。
形式:
loop1:for(int i=0;i<n;i++)
{
loop2:for(int j=i+1;j<n;j++)
{
if(...)
{
break loop1;
}
else
{
continue loop2;
}
}
}
2.7吸血鬼数字(Java)
【问题描述】吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘得到,这对数字各包含乘积的一半位数的数字,数字选取后可任意排序,例如: 1260=21×60 1827=21×87 2187=27×81。写出一个程序,找出4位数的所有吸血鬼数字。
【输入形式】无
【输出形式】输出所有的吸血鬼数字,数字之间已空格分隔。
【样例输入】无
【样例输出】1260 1395 1435 1530 1827 2187 6880
2.8 ip地址判定(Java)
【问题描述】现在IPV4下用一个32位无符号整数来表示,一般用点分方式来显示,点将IP地址分成4个部分,每个部分为8位,表示成一个无符号整数(因此不需要用正号出现),如10.137.17.1,是我们非常熟悉的IP地址,一个地址串中没有空格出现(因为要表示成一个32数字)。>现在需要你用程序来判断IP是否合法。
【输入形式】输入一个ip地址
【输出形式】返回判断的结果YES or NO
【样例输入】
10.138.15.1
【样例输出】
YES
【代码】
package a2;
import java.util.Scanner;
import java.util.Arrays;
public class A8 {
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
String str;//输入的ip地址
String str2;//用"."分割的字符串
str=scan.next();
scan.close();
int len=0;
len=str.length();//ip地址长度
int num=0;//将地址转化为数子
int k=0;//初始化为0,表示.的位置
int flag=0;//为0则合法
for(int i=0;i<len;i++)
{
if(str.charAt(i)=='.')//遇到“.”时,str2表示.之前的字符串
{
str2=str.substring(k,i);
k=i+1;//更新
num= Integer.valueOf(str2);//将str2转化为数字
if(num>=255) flag++;//若num>=255,则ip不合法,令flag++
}
}
str2=str.substring(k,len);//截取.至str最后一个字符
num= Integer.valueOf(str2);
if(num>=255) flag++;
if(flag!=0) System.out.print("NO");//flag不为0,则ip不合法
else System.out.print("YES");
}
}
【知识点】
1、关于字符串的操作
1)获取长度:int len=str.length(); len为字符串str的长度;
2)获取指定索引位置的字符:str.charAt(i);获取字符串str第i个字符;
3)获取子字符串:str.substring(i,j);获取str第i个字符到第j个字符的字符串(不包括第j个字符)
4)Java里转换字符串为整型有两种方式:
- Integer.valueOf(String str)
- Integer.parseInt(String str)
5)把字符串转化为相应的数值:
- int型Integer.parseInt(字符串)
- long型Long.parseLong(字符串)
- double型Double.valueOf(字符串).doubleValue()
关于字符串的更多操作:
https://www.cnblogs.com/StarZhai/p/10577880.html
https://majing.io/posts/10000004271158
2.9 骰子问题旋转(java)
【问题描述】 骰子是个立方体每个面一个数字,初始为左1,右2,前3(观察者方向),后4,上5,下6,用123456表示这个状态。放置在平面上用L表示向左翻转一次,用R表示向右翻转一次,用F表示向前翻转一次,用B表示向后翻转一次,用A表示逆时针旋转90度,用C表示顺时针旋转90度,现从初始状态开始,根据输入的动作序列,计算得到最终的状态。
【输入形式】输入只包含LRFBAC的字母序列,最大长度为50,可重复
【输出形式】输出经过一系列操作后的序列 注:按左右前后上下顺序输出
【样例输入】LB
【样例输出】5 6 1 2 3 4
【注意】
找到规律直接if-else即可,需注意不要把向左/右翻转与顺/逆时针旋转混淆。
【代码】
package a2;
import java.util.Scanner;
import java.util.Arrays;
public class A9 {
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
String str;
str=scan.next();
scan.close();
int len=0;
len=str.length();
int[] a=new int[6];//旋转前的序列
int[] b=new int[6];//旋转后的序列
for(int i=0;i<6;i++)
{
a[i]=i+1;//初始化
}
for(int i=0;i<len;i++)
{
if(str.charAt(i)=='C')
{
b[0]=a[2];
b[1]=a[3];
b[2]=a[1];
b[3]=a[0];
b[4]=a[4];
b[5]=a[5];
}
else if(str.charAt(i)=='A')
{
b[0]=a[3];
b[1]=a[2];
b[2]=a[0];
b[3]=a[1];
b[4]=a[4];
b[5]=a[5];
}
else if(str.charAt(i)=='F')
{
b[0]=a[0];
b[1]=a[1];
b[2]=a[4];
b[3]=a[5];
b[4]=a[3];
b[5]=a[2];
}
else if(str.charAt(i)=='B')
{
b[0]=a[0];
b[1]=a[1];
b[2]=a[5];
b[3]=a[4];
b[4]=a[2];
b[5]=a[3];
}
else if(str.charAt(i)=='L')
{
b[0]=a[4];
b[1]=a[5];
b[2]=a[2];
b[3]=a[3];
b[4]=a[1];
b[5]=a[0];
}
else if(str.charAt(i)=='R')
{
b[0]=a[5];
b[1]=a[4];
b[2]=a[2];
b[3]=a[3];
b[4]=a[0];
b[5]=a[1];
}
for(int j=0;j<6;j++)
{
a[j]=b[j];//复制
}
}
scan.close();
for(int i=0;i<6;i++)
{
System.out.print(b[i]+" ");
}
}
}
2.10 DNA序列(Java)
【问题描述】 一个DNA序列由A/C/G/T四个字母的排列组合组成。G和C的比例(定义为GC-Ratio)是序列中G和C两个字母的总的出现次数除以总的字母数目(也就是序列长度)。在基因工程中,这个比例非常重要。因为高的GC-Ratio可能是基因的起始点。
给定一个很长的DNA序列,以及要求的最小子序列长度,研究人员经常会需要在其中找出GC-Ratio最高的子序列。
【输入形式】输入一个string型基因序列,和int型子串的长度
【输出形式】找出GC比例最高的子串,如果有多个输出第一个的子串
【样例输入】AACTGTGCACGACCTGA 5
【样例输出】GCACG
【代码】
package a2;
import java.util.Scanner;
import java.util.Arrays;
public class A10 {
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
String str;
int n=0;
str=scan.next();//基因序列
n=scan.nextInt();//子串长度
scan.close();
int len=0;
len=str.length();//基因序列长度
String str2="";//比例最高的子串
String str3="";
int num=0;
int max=0;//比例最高的子串的GC个数
for(int i=0;i<len-n+1;i++)
{
str3="";
num=0;
for(int j=i;j<i+n;j++)
{
if(str.charAt(j)=='G'||str.charAt(j)=='C')
{
num++;//GC个数加1
}
str3+=str.charAt(j);//将改子串保存到str3
}
if(num>max) //若有更大值
{
str2=str3;//更新str2
max=num;
}
}
System.out.print(str2);
}
}
【知识点】
1、关于nextInt()、next()和nextLine()的用法
- nextInt(): (nextInt()只读取数值,剩下"\n"还没有读取,并将Scanner类读取依靠的cursor放在数值后面,"\n"前面,因此如果用nextInt()读取后,再用nextLine()读取,读取到的是换行符)
- next(): (next()只读空格之前的数据,并且cursor指向本行)next() 方法遇见第一个有效字符(非空格,非换行符)时,开始扫描,当遇见第一个分隔符或结束符(空格或换行符)时,结束扫描,获取扫描到的内容,即获得第一个扫描到的不含空格、换行符的单个字符串。
- nextLine(): 可以扫描到一行内容并作为一个字符串而被获取到。如果要读取带空格的一串字符串还是需要使用nextLine(),而非next()方法。
更多有关Scanner的用法:
https://blog.csdn.net/weixin_41262453/article/details/88815173