蓝桥杯校级预选赛题
1.计算字符串周期问题
1.1 原题及实例
1.2 思路
? 这道题就是让算出一个字符串中某一个字符串循环的最小周期,那么可以使用String类型的一些方法,比如substring()方法,可以截取从第0个下标到后面index个长度的字符串,然后与i相邻位置后的字符串进行比较,如果相同则index就是最小周期。
? 比较重要的是要了解String类中substring(int startIndex,int endIndex)方法参数代表的意思
public static void main(String[] args){
String s="abcabc";
s.substring(0,2);
}
1.3 代码
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String s=scanner.next();
int i=calu(s);
System.out.println(i);
}
public static int calu(String s){
for(int i=1;i<=s.length();i++){
String s1=s.substring(0,i);
String s2=s.substring(i,i+s1.length());
if(s1.equals(s2)){
return i;
}
}
return 0;
}
}
2.判断无序数列中最近且大的数字
1.1 原题及实例
1.2 思路
? 这个题其实就是计算一个无序数列当中,从后到前,计算距离每一个数字最近且比其大的数字。
? 如果以上思想去思考这个问题,那么就可以使用插入排序的思想去解决这个问题
1.3 代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
ArrayList<Integer> arrayList=new ArrayList<>();
int num=scanner.nextInt();
for(int i=0;i<num;i++){
int j=scanner.nextInt();
arrayList.add(j);
}
sort(num,arrayList);
}
public static void sort(int num,ArrayList<Integer> arrayList){
HashMap<Integer,Integer> hashMap=new HashMap<>();
for (int i=num-1;i>=0;i--){
boolean flag=false;
for (int j=i;j>=0;j--){
if (arrayList.get(i)<arrayList.get(j)){
hashMap.put(i+1,j+1);
flag=true;
break;
}
}
if (!flag){
hashMap.put(i+1,0);
}
}
for (int i=1;i<=num;i++){
System.out.print(hashMap.get(i)+" ");
}
}
}
3.判断字符串中的子字符串
3.1 原题及实例
3.2 思路
? 如果输入一段特点顺序的技能就会输,那么只需要判断一个字符串(即释放技能的顺序)当中是否有某一个字串(即输的技能顺序)即可,如果存在,那么输,如果不存在,那么赢。
3.3 代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
ArrayList<String> arrayList=new ArrayList<>();
String s1="WZY";
for(int i=0;i<num;i++){
String s=scanner.next();
arrayList.add(s);
}
int n=calu(num,s1,arrayList);
System.out.print(n);
}
public static int calu(int num,String s,ArrayList<String> arrayList){
int n=num;
for (int i=0;i<num;i++){
String s1=arrayList.get(i);
if (s1.indexOf(s)!=-1){
n--;
}
}
return n;
}
}
4.给三个数字,判断是否可以组成直角三角形
4.1 原题及实例
4.2 思路
? 这个题灰常简单,判断三个数是否能够组成直角三角形使用勾股定理即可,但是如何输入这些数字还是需要思考一丢丢的。每一行固定输入三个数,那么可以用一个整型数组来存,这类数是需要存num个的组的,所以使用ArrayList集合来存。
4.3 代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
ArrayList<int[]> arrayList=new ArrayList<>();
for(int i=0;i<num;i++){
int[] ints=new int[3];
ints[0]=scanner.nextInt();
ints[1]=scanner.nextInt();
ints[2]=scanner.nextInt();
arrayList.add(ints);
}
calu(num,arrayList);
}
public static void calu(int num,ArrayList<int[]> arrayList){
ArrayList<String> arrayList1=new ArrayList<>();
for (int i=0;i<num;i++){
boolean flag=false;
int[] ints = arrayList.get(i);
Arrays.sort(ints);
if (Math.pow(ints[0],2)+Math.pow(ints[1],2)==Math.pow(ints[2],2)){
flag=true;
}
if (flag){
arrayList1.add("Yes");
}else {
arrayList1.add("No");
}
}
for (int i=0;i<arrayList1.size();i++){
System.out.println("Test"+(i+1)+":");
System.out.println(arrayList1.get(i));
}
}
}
5.计算不规则图形的周长
5.1 原题及实例
5.2 思路
? 从题中可以得出,栅栏的每一个边都是与x轴(或y轴)垂直,通过坐标画出图形如下:
? 根据上图,就可以得出思路,只需要计算出矩形的长和宽就可以计算出栅栏的总长度。矩形的长就是x_max-x_min,矩形的宽就是y_max-y_min。
【注意】:这个题并不难,但是如何满足题目要求从键盘输入,然后完成计算比较难,这个需要仔细思考一下。
5.3 代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
ArrayList<Integer> result=new ArrayList<>();
boolean flag=true;
ArrayList<Integer> arrayList1=new ArrayList<>();
while(true){
ArrayList<int[]> arrayList=new ArrayList<>();
int num=scanner.nextInt();
if(num==0){
break;
}
int[] ints_x=new int[num];
int[] ints_y=new int[num];
for(int i=0;i<num;i++){
ints_x[i]=scanner.nextInt();
ints_y[i]=scanner.nextInt();
}
arrayList.add(ints_x);
arrayList.add(ints_y);
int n=method(num,arrayList);
result.add(n);
}
for(int j=0;j<result.size();j++){
System.out.println("The length is "+result.get(j)+" L");
}
}
public static int method(int num,ArrayList<int[]> arrayList){
int length;
int width;
int[] ints_x=arrayList.get(0);
int[] ints_y=arrayList.get(1);
Arrays.sort(ints_x);
Arrays.sort(ints_y);
length=ints_x[num-1]-ints_x[0];
width=ints_y[num-1]-ints_y[0];
return (length+width)*2;
}
}
6.判断字符串中的字符
6.1 原题及实例
6.2 思路
? 这道题实际非常简单,但是必须要注意一点,字符串中,从左到右,如果")“比”("多,那么这个式子也是错误的,所以判断错误的条件有三个:
- 从左到右,如果")“比”("多,即错误
- 字符串中,压根没有"(“或”)",直接错误
- 字符串中,"(“和”)"的数量不相等,即错误
6.3 代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNextLine()){
String s=scanner.nextLine();
System.out.println(method(s));
}
}
public static String method(String s){
if (s.equals("") || s==null){
return "Wrong";
}
int num1=0;
int num2=0;
int k=0;
int flag=0;
for (int i=0;i<s.length();i++){
if (s.charAt(i)=='('){
k++;
num1++;
flag=1;
}
if (s.charAt(i)==')'){
k--;
num2++;
flag=1;
}
if(num2>num1){
break;
}
}
if(flag==0){
return "Wrong";
}
if (num1==num2){
return "Ok";
}else {
return "Wrong";
}
}
}
7.01背包问题
7.1 原题及实例
7.2 思路
? 这道题的原型就是NASA食物计划问题。这道题是一道多条件限制的01背包问题,和基础的01背包不同的是有两个条件限制,分别的最大体积和最大体重。
? 最后一道题有一个01背包问题,大家可以认识并理解一下01背包问题。
7.3 代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int maxTJ=scanner.nextInt();
int maxZL=scanner.nextInt();
int n=scanner.nextInt();
int[] tj=new int[n];
int[] zl=new int[n];
int[] kll=new int[n];
int[][] dp=new int[maxTJ][maxZL];
for(int i=0;i<n;i++){
tj[i]=scanner.nextInt();
zl[i]=scanner.nextInt();
kll[i]=scanner.nextInt();
}
int result=method(tj,zl,kll,maxTJ,maxZL,n);
System.out.println(result);
}
public static int method(int[] tj,int[] zl,int[] kll,int maxTJ,int maxZL,int n){
if (tj.length==0 || zl.length==0 || kll.length==0){
return 0;
}
int[][] dp=new int[maxTJ+1][maxZL+1];
for (int i=0;i<n;i++){
for (int j=maxTJ;j>=tj[i];j--){
for (int k=maxZL;k>=zl[i];k--){
dp[j][k]=Math.max(dp[j-1][k-1],dp[j-tj[i]][k-zl[i]]+kll[i]);
}
}
}
return dp[maxTJ][maxZL];
}
}
8.多个字符串的最长字串问题
8.1 原题及实例
8.2 思路
? 这个题实际就是求多个字符串的最长字串问题,最经常考的是两个字符串的最长字串问题,但思路其实都一样。
? 需要先将N个字符串中的最小字符串找到,然后使用两个for遍历出其所有的字串,然后在所有的字符串中进行contains()判断,如果都有,那么可以存入TreeMap中,这样就可以将所有的字串找到,存入到了TreeMap中,然后找到TreeMap中前几个长度递增的最后一个字串,即为答案。
【注意】:为什么要用TreeMap,题目中有要求,如果最长字串有多个,那么找到字典值最小的,而TreeMap刚好是根据字典值存入的。
【注意注意注意】:以下代码没有通过所有用例,但是由于太菜,揪了很多头发都没有找到问题所在,有发现问题的同学可以私信我,万分感谢!
8.3 代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int n=scanner.nextInt();
if(n==0){
break;
}
ArrayList<String> arrayList=new ArrayList<>();
for(int i=0;i<n;i++){
String s=scanner.next();
arrayList.add(s);
}
method(arrayList,n);
}
}
public static void method(ArrayList<String> arrayList,int n) {
if (arrayList == null || arrayList.size()==0) {
return;
}
TreeSet<String> set = new TreeSet<>();
String minString = arrayList.get(0);
for (int i = 0; i < arrayList.size(); i++) {
if (minString.length() > arrayList.get(i).length()) {
minString = arrayList.get(i);
}
}
for (int x = 0; x < minString.length(); x++) {
String result = null;
for (int j = x + 1; j <= minString.length(); j++) {
boolean flag=true;
String s = minString.substring(x, j);
for (int k = 0; k < n; k++) {
boolean q = arrayList.get(k).contains(s);
if (!q) {
flag=false;
break;
}
}
if (flag){
result=s;
}
}
if (result != null) {
set.add(result);
}
}
String s1 = "";
Iterator<String> it = set.iterator();
if (set.size() == 0) {
System.out.println("None");
return;
} else {
while (it.hasNext()) {
String a = it.next();
if (s1.length() < a.length()) {
s1 = a;
} else {
break;
}
}
}
System.out.println(s1);
}
}
9.经典01背包问题
9.1
9.1 详细描述
? 给你一个可装载重量为W的背包和N个物品,每个物品有重量和价值两个属性。其中第i个物品的重量为weight[i],价值为value[i],现在让你用这个背包装物品,最多能装的价值是多少?
? 现有W=10,N=4,物体重量和价值如下表:
i(第i个物体)0 | 0 | 1 | 2 | 3 |
---|
W(物体的重量) | 2 | 3 | 4 | 7 | V(物体的价值) | 1 | 3 | 5 | 9 |
9.2 思路
? 先提出一个dp二维数组,在容量为j的时候,存放第i个物体之前所能装载的最大价值,全程会围绕这个数组解释。
? 下面为dp二维数组,列(i)代表第i个物体,行(j)代表背包容量为j的时候,存入当背包容量为j的时候,第i个物体之前所能存入的最大价值。
? 下面以列为单位来看,即以背包容量为前提条件来看能够存入的物体价值:
? 当背包容量为1时,所有物体都无法装进,那么都其价值都为0
? 当背包容量为2时,当i=0,大于物体0的重量,并且此时是第一个物体,那么价值就是这个物体的价值,为1,后面的所有物品重量都比背包容量大,结束。
? 当背包容量为3时,当i=0,大于物体0的重量,并且此时是第一个物体,那么价值就是这个物体的价值,为1;当i=1,大于物体1的重量,那么就出现了装或不装这个物体两种情况,若不装,价值和i-1的价值相同,即dp[i] [j]=dp[i-1] [j]=1,若装,价值为背包容量减去第i个物体的重量所能拿到的价值+第i个物体的价值,即dp[i] [j]=dp[i-1] [j-weight[i]]+value[i],然后比较这个两个值的大小取其最大值,后面的所有物品重量都比背包容量大,结束。
? 后面的每个容量背包都是这样的,遍历每个物体,当物体为第一个时且背包容量大于物体重量,那么其能够装的最大价值就是这个物体的价值;当物体为第二个时且背包容量大于物体重量,那么有两种选择,不装这个物体,价值为dp[i] [j]=dp[i-1] [j];装这个物体,价值为dp[i] [j]=dp[i-1] [j-weight[i]]+value[i],每个背包容量都是这样的,按照这样的情况填完下表为:
i\j | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|
0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 3 | 3 | 4 | 4 | 4 | 4 | 4 | 4 | 2 | 0 | 1 | 3 | 5 | 5 | 6 | 8 | 8 | 8 | 8 | 3 | 0 | 1 | 3 | 5 | 5 | 6 | 9 | 9 | 10 | 12 |
9.3 代码
public static int test0(int[] weight,int[] value,int cap){
int[][] dp=new int[100][cap+1];
if (weight.length==0 || cap<=0){
return 0;
}
for (int j=1;j<cap+1;j++){
for (int i=0;i<weight.length;i++){
if (weight[i]<=j){
if (i==0){
dp[i][j]=weight[i];
}else {
dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);
}
}else {
if (i==0){
dp[i][j]=0;
}else {
dp[i][j]=dp[i-1][j];
}
}
}
}
return dp[weight.length-1][cap];
}
|