第十届蓝桥杯大赛软件类省赛Java大学B组

第十届蓝桥杯大赛软件类省赛Java大学B组_第1张图片

第十届蓝桥杯大赛软件类省赛Java大学B组_第2张图片
第十届蓝桥杯大赛软件类省赛Java大学B组_第3张图片

答案

490

分析

都看过打球把,每个球位都要选一人,那么就不能一个人担任几个球位。
手算:97+99+99+97+98=490 或者 98+99+98+97+98=490 或者 97+99+99+97+98=490

代码

第十届蓝桥杯大赛软件类省赛Java大学B组_第4张图片

答案

100

分析

利用HashSet散列表去重,字符串的subString(开始位置,结束位置)获取字符串子串

注意subString有效长度是:[开始位置,结束位置-1]

代码

import java.util.HashSet;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		HashSet<String> set=new HashSet<String>();
		String str=sc.nextLine();
		for(int i=0;i<str.length();i++){
			for(int j=i;j<str.length();j++){
				String s=str.substring(i,j+1);
				//if(!set.contains(s)){
					set.add(s);
				//}
			}
		}
		System.out.print(set.size());
	}
} 

第十届蓝桥杯大赛软件类省赛Java大学B组_第5张图片

答案

4659

分析

第20190324项可想而知有多大,连BigInteger都装不下,更何况long跟int了。

注意看题意,要我们求第20190324项的最后4位数字,我们每次只要关注后一项的结果的后四位数字就行,所以用%10000,进行保护数据。以免爆表。

方法一:用BigInteger来做,并对d求余
方法二:int类型就够,求余

代码

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		//Scanner sc=new Scanner(System.in);
		//方法一
		/*BigInteger a=BigInteger.ONE;
		BigInteger b=BigInteger.ONE;
		BigInteger c=BigInteger.ONE;
		BigInteger d=BigInteger.ZERO;
		int x=4,n=20190324;
		while(x<=n){
			d=a.add(b).add(c).mod(new BigInteger("10000"));
			a=b;
			b=c;
			c=d;
			x++;
		}
		System.out.println(d);
		System.out.print(d.mod(new BigInteger("10000")));*/
		
		
		//方法二
	/*	int arr[] = new int[20190325];
        arr[1] = arr[2] = arr[3] = 1;
        for(int i = 4; i <= 20190324; i++){
            arr[i] = (arr[i-1] + arr[i-2] + arr[i-3]);  // % 10000
            arr[i] %= 10000;
        }
        System.out.println(arr[20190324]);
	 */
		
		
		//方法三
		long a=1,b=1,c=1,d=3;
		int x=4,n=20190324;
		while(x<=n){
			d=(a%10000+b%10000+c%10000)%10000;
			a=b%10000;
			b=c%10000;
			c=d%10000;
			x++;
		}
		System.out.println(d);
		System.out.print(d%10000);
	}
} 

第十届蓝桥杯大赛软件类省赛Java大学B组_第6张图片

答案

40785

分析

将2019分解成三个不同的正整数,且不能含有2和4

  • 不能为0, 正整数>0,0不是正数也不是负数,所以0不是正整数
  • 三个数,排列组合有3 * 2 * 1=6种情况,所以要除以六个本质上相同的序列。可自定义三个数从小到大排序好。
  • 不包含某元素,利用求余法或者字符串的indexof方法或charAt方法来做

方法见注释
(数据量不算太大,3重纯for循环再等上几秒钟还是能出结果,但最好少用)

代码

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		//Scanner sc=new Scanner(System.in);
		long count=0;
		/*HashSet set=new HashSet(); 
		for(int i=1;i<2019;i++){
			for(int j=1;j<2019;j++){
				for(int k=1;k<2019;k++){
					if(i+j+k>2019){
						break;                                    //时间复杂度大,排列组合有6种情况
					}
					if(i!=j&&i!=k&&j!=k&&i+j+k==2019){
						if(hefa(i)&&hefa(j)&&hefa(k)){count++;}
					}
				}
			}
		}
		System.out.println(count/6);System.out.println(set.size());*/
		
		for(int i=1;i<2019;i++){
			if(hefa(i)){
				for(int j=i+1;j<2019-i;j++){                       //降低了时间复杂度
					int k=2019-i-j;                                //保证了i比j小,还剩3种可能的排列情况
					if(k>0&&hefa(j)&&hefa(k)&&i!=j&&i!=k&&j!=k){   //i j k; i k j; k i j
						count++;
					}
				}
			}
		}
		System.out.println(count/3);
		/*int n = 2019;
		int num = 0;
		for (int i = 1; i < n; i++) {
			if ((i + "").indexOf("2") != -1 || (i + "").indexOf("4") != -1)
				continue;
			for (int j = i + 1; j < n; j++) {
				if ((j + "").indexOf("2") != -1 || (j + "").indexOf("4") != -1)
					continue;
				int k = n - i - j;
				if (i == k || j == k || i == j)
					continue;
				if (k > 0 && (k + "").indexOf("2") == -1 && (k + "").indexOf("4") == -1)
					num++;
			}
		}
		System.out.println(num / 3);*/

	}
	public static boolean hefa(int x){
		while(x>0){
			if(x%10==2||x%10==4){
				return false;
			}
			x/=10;
		}
		return true;
	}
} 
import java.util.Scanner;
public class Main {	
	public static void main(String arg[]){
		Scanner sc=new Scanner(System.in);
		long ans=0L;
		for(int i=1;i<2019;i++){
			for(int j=i+1;j<2019-i;j++){
				for(int k=j+1;k<=2019-i-j;k++){
					if(i+k+j==2019){
						int x1=i,x2=j,x3=k;
						boolean flag=true;
						while(x1>0){
							if(x1%10==2||x1%10==4){
								flag=false;
							}
							x1/=10;
						}
						while(x2>0){
							if(x2%10==2||x2%10==4){
								flag=false;
							}
							x2/=10;
						}
						while(x3>0){
							if(x3%10==2||x3%10==4){
								flag=false;
							}
							x3/=10;
						}
						if(flag){
							ans++;
						}
					}
				}
			}
		}
		System.out.print(ans);
	}
}

import java.util.Scanner;
public class Main {	
	public static void main(String arg[]){
		Scanner sc=new Scanner(System.in);
		long ans=0L;
		for(int i=1;i<2019;i++){
			if(hefa(i)){
				for(int j=i+1;j<2019-i;j++){
					if(hefa(j)){
						int k=2019-i-j;
						if(hefa(k)&&k>j){
							ans++;
						}
					}
				}
			}
		}
		System.out.print(ans);
	}
	public static boolean hefa(int i){
		while(i>0){
			if(i%10==2||i%10==4){
				return false;
			}
			i/=10;
		}
		return true;
	}
}

第十届蓝桥杯大赛软件类省赛Java大学B组_第7张图片

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

答案

emmm…考场上感觉时间也不充足,放弃。。

分析

dfs+最短路径

代码

第十届蓝桥杯大赛软件类省赛Java大学B组_第8张图片

分析

模拟题,模拟下就可以

方法:求余法、字符串判断法

代码

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		long sum=0;
		for(int i=1;i<=n;i++){
			int x=i;
			while(x>0){
				if(x%10==2||x%10==0||x%10==1||x%10==9){
					sum+=i;
					break;
				}
				x/=10;
			}
		}
		System.out.print(sum);
	}
} 

第十届蓝桥杯大赛软件类省赛Java大学B组_第9张图片
第十届蓝桥杯大赛软件类省赛Java大学B组_第10张图片

分析

模拟题,排序+分析。见代码

代码

AC-时间较快

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Main {	
	public static void main(String arg[]){
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt(),m=sc.nextInt(),t=sc.nextInt();
		ArrayList<Integer>[] info=new ArrayList[n+1];
		int[] hc=new int[n+1];
		int ans=0;
		for(int i=1;i<=n;i++){
			info[i]=new ArrayList<Integer>();
		}
		for(int i=1;i<=m;i++){
			int ts=sc.nextInt();
			int id=sc.nextInt();
			info[id].add(ts);
		}
		for(int i=1;i<=n;i++){
			Collections.sort(info[i]);
			if(info[i].size()==0){
				continue;
			}
			long yxj=0L;
			int pre=info[i].get(0);
			for(int j=0;j<info[i].size();j++){    //这里每一时刻最好一步一步模拟
				int cha=info[i].get(j)-pre;
				if(cha>1){
					yxj-=(info[i].get(j)-pre-1);
				}
				if(yxj<0){
					yxj=0;
				}
				if(yxj<=3){          //在每一时刻只要小于等于3就退出缓存区
					hc[i]=0;
				}
				yxj+=2;
				if(yxj>5){
					hc[i]=1;
				}
				pre=info[i].get(j);
			}
			yxj-=(t-info[i].get(info[i].size()-1));  //到最后t时刻
			if(yxj<=3){          //在每一时刻只要小于等于3就退出缓存区
				hc[i]=0;
			}
		}
		for(int i=1;i<=n;i++){
			if(hc[i]==1){
				ans++;
			}
		}
		System.out.print(ans);
	}
}

AC-时间快

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
	public class Main {                                 //内存155372     时间1450
		public static void main(String[] args) {
			Scanner sc=new Scanner(System.in);
			int n=sc.nextInt(),x=1; //外卖店数
			int m=sc.nextInt();  //订单信息数
			int t=sc.nextInt();  //t时刻以内
			//int[][] dingdan=new int[t+1][n+1];
			ArrayList<Integer>[] g=new ArrayList[t+1];
			
			int[] youxianji=new int[n+1];
			int[] hc=new int[n+1];
			for(int i=1;i<=t;i++)
				g[i]=new ArrayList<Integer>();
			while(x<=m){
				x++;
				int ts=sc.nextInt();
				int id=sc.nextInt();
				g[ts].add(id);
			}
			
			for(int i=1;i<t+1;i++){
				int[] time=new int[n+1];
				for(int j=0;j<g[i].size();j++){
					time[g[i].get(j)]++;
					/*if(!g[i].contains(j)){
						if(youxianji[j]!=0){
							youxianji[j]--;
						}
					}else{
						youxianji[j]+=2;
					}
					if(youxianji[j]>5){
						hc[j]=1;
					}else if(youxianji[j]<=3){
						hc[j]=0;
					}*/
				}
				for(int z=1;z<n+1;z++){
					if(time[z]==0){
						if(youxianji[z]!=0){
							youxianji[z]--;
						}
					}else{
						youxianji[z]+=2*time[z];
					}
					if(youxianji[z]>5){
						hc[z]=1;
					}else if(youxianji[z]<=3){
						hc[z]=0;
					}
				}
				
			}
			int count=0;
			for(int i=1;i<n+1;i++){
				if(hc[i]==1){
					count++;
				}
			}
			System.out.print(count);
		}
	} 

内存超限-通过90%

import java.util.Scanner;
public class Main {   //内存526896   时间1898
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt(); //外卖店数
		int m=sc.nextInt();  //订单信息数
		int t=sc.nextInt();  //t时刻以内
		int[][] dingdan=new int[t+1][n+1];
		int[] youxianji=new int[n+1];
		int[] hc=new int[n+1];
		while(m>0){
			m--;
			int ts=sc.nextInt();
			int id=sc.nextInt();
			dingdan[ts][id]++;
		}
		
		for(int i=1;i<t+1;i++){
			for(int j=1;j<n+1;j++){
				if(dingdan[i][j]==0){
					if(youxianji[j]!=0){
						youxianji[j]--;
					}
				}else{
					youxianji[j]+=2*dingdan[i][j];
				}
				if(youxianji[j]>5){
					hc[j]=1;
				}else if(youxianji[j]<=3){
					hc[j]=0;
				}
			}
		}
		int count=0;
		for(int i=1;i<n+1;i++){
			if(hc[i]==1){
				count++;
			}
		}
		System.out.print(count);
	}
} 

AC-时间较慢

import java.util.Scanner;
public class Main {                                 //内存178820   时间1429
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt(); //外卖店数
		int m=sc.nextInt(),mm=m;  //订单信息数
		int t=sc.nextInt();  //t时刻以内
		//int[][] dingdan=new int[t+1][n+1];
		int[] tarr=new int[m];
		int[] idarr=new int[m];
		int[] youxianji=new int[n+1];
		int[] hc=new int[n+1];
		int p=0;
		while(m>0){
			m--;
			tarr[p]=sc.nextInt();
			idarr[p]=sc.nextInt();
			p++;
		}
		for(int j=1;j<t+1;j++){
			int[] time=new int[n+1];
			for(int i=0;i<mm;i++){
				if(tarr[i]==j){
					youxianji[idarr[i]]+=2;
					time[idarr[i]]=1;
				}
			}
			for(int v=1;v<n+1;v++){
				if(time[v]!=1){
					//System.out.println(j+"时刻"+v+"没有订单数");
					if(youxianji[v]!=0){
						youxianji[v]--;
					}
				}else{
					//System.out.println(j+"时刻"+v+"有订单数");
				}
				if(youxianji[v]>5){
					hc[v]=1;
				}else if(youxianji[v]<=3){
					hc[v]=0;
				}
			}
		}
		int count=0;
		for(int i=1;i<n+1;i++){
			if(hc[i]==1){
				count++;
			}
		}
		System.out.print(count);
	}
} 

第十届蓝桥杯大赛软件类省赛Java大学B组_第11张图片
第十届蓝桥杯大赛软件类省赛Java大学B组_第12张图片
第十届蓝桥杯大赛软件类省赛Java大学B组_第13张图片

分析

先用indexof找到Alice和Bob出现的下标,放到数组里

利用滑动窗口算法思想进行算法优化,减少时间复杂度

常规方法:两个不定长数组,j下标从0开始Alice找Bob,时间超限55

存放Bob位置运用数组方法:数组下标差的到的中间那段,找Bob为1的index有几个,然后相加,时间超限82

滑动窗口算法思想优化算法:循环Alice时候,下一次的Alice寻找Bob的开始和结束位置是上一次Alice的寻找Bob的开始和结束位置。

注意事项:sc.nextInt()和sc.nextLine()的结合使用时需要吞掉一个换行符。

代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int k=sc.nextInt();String kong=sc.nextLine();
        long count=0;
        String str=sc.nextLine();
        ArrayList<Integer> alice=new ArrayList<Integer>();
        ArrayList<Integer> bob=new ArrayList<Integer>();
        //int[] bob=new int[1000000];
        int froma=0,fromb=0;
        while(true){
            int indexa=str.indexOf("Alice",froma);
            froma=indexa+4;
            if(indexa==-1){froma=str.length()-1;}
            int indexb=str.indexOf("Bob",fromb);
            fromb=indexb+2;
            if(indexb==-1){fromb=str.length()-1;}
            if(indexa==-1&&indexb==-1){
                break;
            }
            if(indexa!=-1&&indexa+4<=str.length()-1){
                if((indexa+5==str.length()&&feizimu(str.charAt(indexa-1)))||(indexa==0&&feizimu(str.charAt(indexa+5)))||(feizimu(str.charAt(indexa-1))&&feizimu(str.charAt(indexa+5)))){
                    alice.add(indexa);
                }
            }
             
            if(indexb!=-1&&indexb+2<=str.length()-1){
                if((indexb+3==str.length()&&feizimu(str.charAt(indexb-1)))||(indexb==0&&feizimu(str.charAt(indexb+3)))||(feizimu(str.charAt(indexb-1))&&feizimu(str.charAt(indexb+3)))){
                    bob.add(indexb);
                    //bob[indexb]++;
                }
            }
        }
        //int As = alice.size(), Bs = bob.size();       //As与Bs分别为两数组元素个数 
        //int bl = 0, br = 0; 
        int j=0,m=0; 
        for(int i=0;i<alice.size();i++){
            /*int j=alice.get(i)-k-3;
            if(j<0){
                j=0;
            }
            int m=alice.get(i)+k+5;
            if(m>=str.length()){
                m=str.length()-1;            //此方法(Alice找Bob,Bob位置用下标定义)时间超限82
            }
            for(;j<=m;j++){
                if(bob[j]!=0){
                    count++;
                }
            }*/
             
            /*while(bl < Bs && bob.get(bl)< alice.get(i) - k - 3)    bl++;   //维护窗口左边界 
            while(br < Bs && bob.get(br) <= alice.get(i) + k + 5)   br++;   //维护窗口右边界 
            count += br - bl;    */                     //下一次Alice的j和m都是从上一次的j和m开始,ac通过
             
             
            /*for(int j=0;jalice.get(i)&&bob.get(j)-alice.get(i)<=k+5){
                    count++;                       //j每次从0开始,时间超限82
                }
                if(bob.get(j)-alice.get(i)>k+5){
                    break;
                }
            }*/
             
            for(;j<bob.size();j++){
                if(alice.get(i)-bob.get(j)<=k+3){
                    break;
                }                           //下一次Alice的j和m都是从上一次的j和m开始,ac通过
                                          // 使用滑动窗口的算法思想来优化算法,否则将超时。
            }
            for(;m<bob.size();m++){
                if(bob.get(m)-alice.get(i)>k+5){
                    break;
                }                 
            }
            count+=m-j;
        }
        System.out.println(count);
         
    }
    public static boolean feizimu(char ch){
        if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
            return false;
        }else{
            return true;
        }
    }
}
import java.util.ArrayList;
import java.util.Scanner;
public class Main {	
	static String str;
	public static void main(String arg[]){
		Scanner sc=new Scanner(System.in);
		int k=sc.nextInt();String kong=sc.nextLine();
		str=sc.nextLine();
		ArrayList<Integer> alice=new ArrayList<>();
		ArrayList<Integer> bob=new ArrayList<>();
		int index=0;
		long ans=0L;
		while(index<str.length()){
			index=str.indexOf("Alice", index);
			if(index==-1){
				break;
			}
			if(hefa(index,5)){
				alice.add(index);
			}
			index+=4;
		}
		index=0;
		while(index<str.length()){
			index=str.indexOf("Bob", index);
			if(index==-1){
				break;
			}
			if(hefa(index,3)){
				bob.add(index);
			}
			index+=2;
		}
		int left=0,right=0;
		for(int i=0;i<alice.size();i++){
			while(left<bob.size()){
				if(bob.get(left)+3+k>=alice.get(i)){   //加上Bob的长度
					break;
				}
				left++;
			}
			while(right<bob.size()){
				if(bob.get(right)>alice.get(i)+k+5){
					break;
				}
				right++;
			}
			ans+=(right-left);
		}
		System.out.print(ans);
	}
	public static boolean hefa(int index,int len){
		char ch1='0',ch2='0';
		if(index>0){
			ch1=str.charAt(index-1);
			if((ch1>='A'&&ch1<='Z')||(ch1>='a'&&ch1<='z')){
				return false;
			}
		}
		if(index+len!=str.length()){
			ch2=str.charAt(index+len);
			if((ch2>='A'&&ch2<='Z')||(ch2>='a'&&ch2<='z')){
				return false;
			}
		}
		return true;
	}
}

第十届蓝桥杯大赛软件类省赛Java大学B组_第14张图片
第十届蓝桥杯大赛软件类省赛Java大学B组_第15张图片

分析

后缀表达式:可以包括括号,且括号可以在任何位置

当 m=0 没有减号 时:

直接全部相加,就是最大数

当 m!=0 时:
当整数全是正整数时,从小到大排序,最小的数前面是减号,其他全是加号。
例如:-(1-2-3)+4+5 =》转化成5+4+3+2-1,无论有几个减号,结果要最大都是直接减去最小数,其他相加

当全是负整数时,除了最大数,其他所有的数绝对值相加,例如:
-1 -(-2-3-4-5) =》 -1+2+3+4+5

当有正有负时,从小到大排序,负数全为正,其他相加,例如:
2个加号 3个减号
数:-1 -2 3 4 5 6
6+5+4-(-1)-(-2-3)=1+2+3+4+5+6

总结:后缀表达式要最大,最大值减去最小值+其他数的绝对值

代码

import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt(),m=sc.nextInt(),len=n+m+1;;
        int[] a=new int[len];
        long ans=0;
        for(int i=0;i<len;i++){
            a[i]=sc.nextInt();
            ans+=a[i];
        }
        Arrays.sort(a);
        if(m==0){         //只有+号的时候
            System.out.println(ans);
            return;
        }else{
            if(a[0]>=0){ //全是正数    其他数之和减去最小数       
                ans=a[len-1];
                for(int i=len-2;i>0;i--){
                    ans+=a[i];
                }
                ans-=a[0];
            }else if(a[len-1]<=0){     //全负数  最大数不加绝对值 其他数全绝对值 相加
                ans=a[len-1];
                for(int i=0;i<len-1;i++){
                    ans+=Math.abs(a[i]);
                }
            }else{     //有正有负 全部加上绝对值 
                ans=0;
                for(int i=0;i<len;i++){
                    ans+=Math.abs(a[i]);
                }
            }
        }
        System.out.println(ans);
    }
}

第十届蓝桥杯大赛软件类省赛Java大学B组_第16张图片
第十届蓝桥杯大赛软件类省赛Java大学B组_第17张图片
第十届蓝桥杯大赛软件类省赛Java大学B组_第18张图片

分析

代码

你可能感兴趣的:(刷题,java,蓝桥杯,算法)