第十一届蓝桥杯大赛软件类省赛第二场(Java研究生组)

本文档展示了多个Java程序,涵盖了数论、日期处理、排序、统计分析、图形划分等多个算法问题。通过分析代码,可以学习到如何计算约数个数、处理日期回文、解决平面分割问题、实现蛇形填数、优化排序序列、统计成绩分布以及作物杂交路径等算法。这些代码实例展示了在实际问题中应用算法的技巧和策略。
摘要由CSDN通过智能技术生成

在这里插入图片描述

package com.lanqiao.十一届省赛第二场Java研究生组;

public class Class_01约数个数 {

	public static void main(String[] args) {
		int ans=0;
		for (int i = 1; i <= 78120; i++) {
			if (78120%i==0) {
				ans++;
			}
		}
		System.out.println(ans);//96
	}
}

在这里插入图片描述

package com.lanqiao.十一届省赛第二场Java研究生组;

public class Class_02跑步锻炼 {

	public static void main(String[] args) {
		int[] month=new int[13];
		int ans1=0;
		int ans2=0;//记录特殊的天数。
		int week=5;//取值1-7,第一天是星期六
		month[1]=month[3]=month[5]=month[7]=month[8]=month[10]=month[12]=31;
		month[4]=month[6]=month[9]=month[11]=30;
		loop:
		for (int i = 2000; i <=2020 ; i++) {
			month[2]=(i%400==0)||(i%4==0&&i%100!=0)?29:28;
			int mon=(i==2020)?10:12;
			for (int j = 1; j <=mon ; j++) {
				
				for (int k = 1; k <= month[j]; k++) {
					if (i==2020&&j==10&&k==1) {
						ans1++;
						ans2++;
						break loop;
					}
					ans1++;//第一天从0加到1
					week=(week+1)%7;//第一天就是星期六。
					if (k==1||week==1) {
						ans2++;
					}
					
				}
			}
		}
		System.out.println(ans1+ans2);//8879
		
	}
}

在这里插入图片描述

package com.lanqiao.十一届省赛第二场Java研究生组;

public class Class_03平面分割 {

	public static void main(String[] args) {
		System.out.println(fun1(20));//211,20条直线划分区域数
		System.out.println(fun2(20));//1391,20条直线,20个圆
	}
	
	//只考虑直线,有n-1条直线,分出区域数最大为fun1(n-1),则第n条直线
	//与前面n-1条直线相交,且交点不重合,由此分成的区域数最大,第n条直线被分成
	//n-2个线段和2个射线,线段和射线将原来已有的区域一分为二。
	//故n条直线的区域数:fun1(n)=fun1(n-1)+n
	static int fun1(int n) {
		if (n==1) {
			return 2;
		}
		return fun1(n-1)+n;
	}
	
	//现在考虑20条直线与一个圆区域划分问题,圆与20条直线相交,且交点不重合,
	//则划分区域数最多。20条直线将圆分成40个线段,线段将原有区域一分为二,
	//故此时区域数为211+40=251.
	//20条直线与n-1个圆划分的区域数最多为fun2(n-1),则第n个圆不仅与直线相交,
	//还要与n-1个圆相交,则第n个圆被分成的线段数是:20*2+2*(n-1)
	static int fun2(int n) {
		if (n==1) {
			return 251;
		}
		return fun2(n-1)+40+2*(n-1);
	}
}

在这里插入图片描述

package com.lanqiao.十一届省赛第二场Java研究生组;

public class Class_04蛇形填数 {

	//761,没什么好说的,找规律就完事啦。
}

在这里插入图片描述

package com.lanqiao.十一届省赛第二场Java研究生组;

public class Class_05排序 {

	//字典序最小,字母不重复,长度最短,逆序数最多
	//ba,cba,dcba
	//逆序数为1,1+2,1+2+3
	//设最短的逆序长度为n,
	//则1+2+3+...+(n-1)=n(n-1)/2;
	//n=15时,逆序数为105;序列为onmlkjihgfedcba
	//如何减少5次,将j移到前面来,即jonmlkihgfedcba
}

在这里插入图片描述

package com.lanqiao.十一届省赛第二场Java研究生组;

import java.util.Scanner;

public class Class_06成绩统计 {

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt();
		int[] arr=new int[n];
		for (int i = 0; i < arr.length; i++) {
			arr[i]=scanner.nextInt();
		}
		
		double ans1=0;//及格人数
		double ans2=0;//优秀人数
		for (int i = 0; i < arr.length; i++) {
			if (arr[i]>=60) {
				ans1++;
			}
			if (arr[i]>=85) {
				ans2++;
			}
		}
		System.out.println(Math.round(ans1*100/n)+"%");
		System.out.println(Math.round(ans2*100/n)+"%");
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.lanqiao.十一届省赛第二场Java研究生组;

import java.text.SimpleDateFormat;
import java.util.Scanner;

public class Class_07回文日期 {

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		String s=scanner.nextLine();
		boolean condition1=false;//第一个回文日期
		boolean condition2=false;//AB型的回文日期
		int year=Integer.parseInt(s.substring(0,4));//得到年
		for (int i = year; !condition1||!condition2; i++) {//枚举每一年,然后反转拼接构成回文日期,之后就是判断此日期是否合法
			//以及是否符合ABAB型
			StringBuilder sb=new StringBuilder(i+"");
			String string=sb.toString()+sb.reverse().toString();
			if (isDate(string)&&!condition1&&string.compareTo(s)>0) {
				System.out.println(string);
				condition1=true;//标志普通的回文日期已找到
			}
			if (isDate(string)&&!condition2&&string.compareTo(s)>0
					&&string.substring(0, 2).equals(string.substring(2, 4))) {
				System.out.println(string);
				condition2=true;//标志ABBA型找到
			}
		}
		
	}
	
	static boolean isDate(String str) {//判断是合法日期否
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		String s=str.substring(0,4)+"-"
				+str.substring(4,6)+"-"+str.substring(6,8);
		try {
			sdf.setLenient(false);//设置为false严格解析日期,若不合法抛出异常
			sdf.parse(s);
		} catch (Exception e) {
			return false;
		}
		return true;
		
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.lanqiao.十一届省赛第二场Java研究生组;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

public class Class_08作物杂交 {

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int N=scanner.nextInt();//作物种类总数
		int M=scanner.nextInt();//初始种子的类型数
		int K=scanner.nextInt();//杂交的方案数
		int T=scanner.nextInt();//目标种子的编号
		int[] time=new int[N+1];//i种作物的种植时间
		for (int i = 1; i < time.length; i++) {
			time[i]=scanner.nextInt();
		}
		Set<Integer> sets=new HashSet<>();//存放初始的编号
		for (int i = 0; i < M; i++) {
			int n=scanner.nextInt();
			sets.add(n);
		}
		int[][] za=new int[N+1][N+1];
		for (int i = 0; i < za.length; i++) {
			for (int j = 0; j < za.length; j++) {
				za[i][j]=0;
			}
		}
		for (int i = 1; i <= K; i++) {
			int j=scanner.nextInt();
			int k=scanner.nextInt();
			int l=scanner.nextInt();
			za[j][k]=l;//编号j,k杂交得l
		}
		
		//min[i]记录产生编号i种子的最短杂交时间。
		int[] min=new int[N+1];
		//初始化
		for (int i = 0; i < min.length; i++) {
			min[i]=Integer.MAX_VALUE;
		}
		
		Iterator<Integer> it=sets.iterator();
		while(it.hasNext()) {
			Integer i=it.next();
			min[i]=0;
		}
		
		for (int l = 0; l < K; l++) {//每用一种方案就加一
			for (int i = 1; i < min.length; i++) {
				for (int j = 1; j < min.length; j++) {
					if (i!=j&&sets.contains(i)&&sets.contains(j)&&za[i][j]!=0) {
						sets.add(za[i][j]);
						//更新加入的种子其产生的时间:杂交的时间(取种植时间最长的)+杂交的两个种子以前杂交出来的最大时间
						int tmp=Math.max(time[i], time[j])+Math.max(min[i], min[j]);
						//可能后面有产生相同种子的方案,比较两种产生相同种子的所用的时间
						min[za[i][j]]=Math.min(min[za[i][j]], tmp);//和以前产生同样种子的方案比较谁快
						//使用了一种方案,将其置零,下次再循环就找不到它。
						za[i][j]=0;
					}
				}
			}
		}
		
		System.out.println(min[T]);
	}
	
	
}

package com.lanqiao.十一届省赛第二场Java研究生组;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

public class Class_08作物杂交改进 {

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int N=scanner.nextInt();//作物种类总数
		int M=scanner.nextInt();//初始种子的类型数
		int K=scanner.nextInt();//杂交的方案数
		int T=scanner.nextInt();//目标种子的编号
		int[] time=new int[N+1];//i种作物的种植时间
		for (int i = 1; i < time.length; i++) {
			time[i]=scanner.nextInt();
		}
		Set<Integer> sets=new HashSet<>();//存放初始的编号
		for (int i = 0; i < M; i++) {
			int n=scanner.nextInt();
			sets.add(n);
		}
		
		List<Point> plans=new ArrayList<>();
		for (int i = 1; i <= K; i++) {
			int j=scanner.nextInt();
			int k=scanner.nextInt();
			int l=scanner.nextInt();
			Point point=new Point(j, k, l);//存放三元组
			plans.add(point);
		}
		
		//min[i]记录产生编号i种子的最短杂交时间。
		int[] min=new int[N+1];
		//初始化
		for (int i = 0; i < min.length; i++) {
			min[i]=Integer.MAX_VALUE;
		}
		
		Iterator<Integer> it=sets.iterator();
		while(it.hasNext()) {
			Integer i=it.next();
			min[i]=0;
		}
		
		while(true) {
			Point point=null;
			Set<Integer> temp=new HashSet<>();
			for (int i = 0; i < plans.size(); i++) {
				point=plans.get(i);
				if (sets.contains(point.x)&&sets.contains(point.y)) {
					int tmp=Math.max(time[point.x], time[point.y])+Math.max(min[point.x], min[point.y]);
					min[point.z]=Math.min(min[point.z], tmp);
					temp.add(point.z);
				}
			}
			sets.addAll(temp);
			if (sets.size()==N) {
				break;
			}
		}

		System.out.print(min[T]);
	}
	
}

class Point{
	int x;
	int y;
	int z;
	public Point(int x,int y,int z) {
		this.x=x;
		this.y=y;
		this.z=z;
	}
}

package com.lanqiao.十一届省赛第二场Java研究生组;

import java.util.Scanner;

public class Class_08作物杂交改进2 {

	static int MAXN=2000+5;
	static int n,m,k,goal;
	static int[] t=new int[MAXN];//种植时间
	static boolean[] have_k=new boolean[MAXN];//有这个种子就设置为true
	static int[][] zajiao=new int[MAXN][MAXN];//存放杂交方案
	static int limit_time;
	static class Father{
		int num;//记录产生这个种子的方案数
		int[] u=new int[MAXN];
		int[] v=new int[MAXN];
		int limtime;//产生这个给种子的最少时间
	}
	static Father[] fa=new Father[MAXN];
	
	static void input() {
		for (int i = 0; i < fa.length; i++) {
			fa[i]=new Father();
		}
		Scanner scanner=new Scanner(System.in);
		n=scanner.nextInt();
		m=scanner.nextInt();
		k=scanner.nextInt();
		goal=scanner.nextInt();
		for (int i = 1; i <= n; i++) {
			t[i]=scanner.nextInt();
		}
		for (int i = 1; i <= m; i++) {
			int z=scanner.nextInt();
			have_k[z]=true;//初始化已有的种子
		}
		for (int i = 1; i <= k; i++) {
			int u,v,w;
			u=scanner.nextInt();
			v=scanner.nextInt();
			w=scanner.nextInt();
			zajiao[u][v]=zajiao[v][u]=w;
			int teq=++fa[w].num;
			if (t[u]<t[v]) {
				int t=u;
				u=v;
				v=t;
			}
			fa[w].u[teq]=u;
			fa[w].v[teq]=v;
		}
	}
	
	static boolean dfs(int x) {//遍历这个种子的产生过程
		if (fa[x].num==0) {//x种子没有相应的杂交方案使他产生
			return false;
		}
		for (int i = 1; i <= fa[x].num; i++) {//遍历每个产生该种子的方案
			int v=fa[x].v[i];
			int u=fa[x].u[i];
			if (!have_k[u]) {//初始种子中没有u
				if (!dfs(u)) {//dfs(u)返回false意味着没有方案产生u
					continue;//直接看下一个方案
				}
			}
			if (!have_k[v]) {//初始种子中没有v
				if (!dfs(v)) {
					continue;
				}
			}
			
			if (fa[x].limtime==0) {
				fa[x].limtime=Math.max(fa[u].limtime, fa[v].limtime)+Math.max(t[u], t[v]);
			}else {
				fa[x].limtime=Math.min(fa[x].limtime, Math.max(fa[u].limtime, fa[v].limtime)+Math.max(t[u], t[v]));
			}
		}
		have_k[x]=true;
		return true;
	}
	public static void main(String[] args) {
		input();
		dfs(goal);
		System.out.println(fa[goal].limtime);
	}
}

在这里插入图片描述

package com.lanqiao.十一届省赛第二场Java研究生组;

import java.security.acl.LastOwnerException;
import java.util.Scanner;

public class Class_09子串分值 {

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		String str=scanner.nextLine();
		int len=str.length();
		int[] pre=new int[len];//前驱字符
		int[] nxt=new int[len];//后继字符
//		for (int i = 0; i < len; i++) {
//			int j;
//			for (j = i-1; j >=0; j--) {
//				if (str.charAt(j)==str.charAt(i)) {
//					pre[i]=j;
//					break;
//				}
//			}
//			if (j<0) {
//				pre[i]=-1;
//			}
//		}
//		for (int i = 0; i < len; i++) {
//			int j;
//			for ( j= i+1; j < len; j++) {
//				if (str.charAt(i)==str.charAt(j)) {
//					nxt[i]=j;
//					break;
//				}
//			}
//			if (j==len) {
//				nxt[i]=len;
//			}
//		}
		//上述的初始化还可以优化。复杂度变成一重循环
		int[] last=new int[26];
		for (int i = 0; i < 26; i++) {
			//暂时存储i+'a'字符的位置索引,因为下面循环中输入字符串
			//第一个字符无前驱,其前驱索引设为-1,
			//所以这里初始化为-1.
			last[i]=-1;
		}
		for (int i = 0; i < len; i++) {
			int x=str.charAt(i)-'a';//找到last中相关字符
			pre[i]=last[x];//把x+'a'字符的索引位置赋值给pre[i]
			last[x]=i;//更新x+'a'字符的位置索引为i,此i会作为后面循环的遇到与x+'a'相同字符的前驱。
		}
		for (int i = 0; i < 26; i++) {
			last[i]=len;
		}
		for (int i = len-1; i >= 0; i--) {
			int x=str.charAt(i)-'a';
			nxt[i]=last[x];
			last[x]=i;//此i会作为后面循环遇到相同字符的后继
		}
		
		int ans=0;
		for (int i = 0; i < len; i++) {
			ans+=(i-pre[i])*(nxt[i]-i);
		}
		System.out.println(ans);
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.lanqiao.十一届省赛第二场Java研究生组;

import java.util.Scanner;

public class Class_10装饰珠 {

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int[] level=new int[5];//存放每个等级的孔数
		int total=0;//记录总孔数
		for (int i = 1; i <= 6; i++) {
			int n=scanner.nextInt();
			for (int j = 0; j < n; j++) {
				int l=scanner.nextInt();
				level[l]++;
				total++;
			}
		}
		int M=scanner.nextInt();//珠子种类
		int[] lev=new int[M+1];//记录每种珠子的等级
		int[][] w=new int[M+1][];//记录每种珠子的价值与数量的关系
		for (int i = 1; i <= M; i++) {
			lev[i]=scanner.nextInt();
			int p=scanner.nextInt();
			w[i]=new int[p+1];
			for (int j = 1; j <= p; j++) {
				w[i][j]=scanner.nextInt();
			}
		}
		
		//dp[i][j]表示前i种珠子放入j个孔中所产生的最大价值
		int[][] dp=new int[M+1][total+1];
		int sum=0;
		int kind=0;//记录判断过的珠子类
		for (int L = 4; L >=1 ; L--) {
			sum+=level[L];//开放的孔数。
			if (sum==0) {
				continue;
			}
			for (int i = 1; i <= M; i++) {//第i种珠子
				if (lev[i]==L) {//例如:3等级的珠子可以放入3,4等级的孔。
					kind++;
					for (int j = 1; j <= sum; j++) {
						dp[kind][j]=dp[kind-1][j];//记录第kind种珠子不放入孔中
					}
					
					//放j个第i种珠子
					for (int j = 1; j < w[i].length; j++) {
						for (int j2 = sum; j2 >= j; j2--) {
							//着重理解这个,每种珠子,放多少个,取最大。
							//放1个该种珠子与原来不放这个给珠子进行比较
							//放2个珠子与原来放1个珠子的产生的最大价值进行比较,取大的。
							dp[kind][j2]=Math.max(dp[kind][j2], dp[kind-1][j2-j]+w[i][j]);
						}
					}
				}
			}
		}
		System.out.println(dp[kind][sum]);
	}
}

仅记录自己做题的情况。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值