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]);
}
}
仅记录自己做题的情况。