3月蓝桥集训三周总结(Java解析)
没有那么多天赋异禀
优秀的人总是在努力翻山越岭
你所看到的惊艳,都曾被平庸历练
接受自己的普通,然后拼尽全力的去与众不同
成为你想成为的人,什么时候都不晚
追赶日月,不苟于山川
1.斐波那契与7
问题描述
答案提交
代码解析
暴力求解
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
System.out.println("26960268160");
scan.close();
}
}
2.小蓝做实验
问题描述
答案提交
代码解析
文件读写 + BigInteger.isProbablePrime()。
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println(342693);
scan.close();
}
}
3.质因数个数
问题描述
输入输出格式
样例输入输出及样例
代码解析
自己的笨方法,前面的只能过40,后者学会了一个新的求质约数的方法。
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
long sum=0;
long n=sc.nextLong();
for(int i=1;i<=n;i++){
if(zhishu(i)&&n%i==0){
sum++;
}
}
System.out.println(sum);
sc.close();
}
public static boolean zhishu(int m){
if(m==1){
return false;
}
if(m!=2){
for(int i=2;i<=Math.sqrt(m);i++){
if(m%i==0){
return false;
}
}
}
return true;
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
long n = scan.nextLong();
int res = 0;
for (int i = 2; (long)i * i< n; i++) {
if(n%i == 0) {
res++;
}
while(n%i==0) {
n = n/i;
}
}
if(n>1) {
res++;
}
System.out.println(res);
}
}
4.英文字母
问题描述
输入输出格式
样例输入输出及评测用例
代码解析
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
int n=sc.nextInt();
if(n>=1&&n<=26){
System.out.println((char)('A'+n-1));
}else{
return;
}
sc.close();
}
}
5.单词分析
题目描述
输入输出描述
输入输出及样例评测
代码解析
和字符统计一模一样,记得最后加break
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
int []m=new int[26];
String str;
str=sc.next();
for(int i=0;i<str.length();i++){
m[str.charAt(i)-'a']++;
}
int max=0;
for(int i=0;i<m.length;i++){
max=Math.max(max,m[i]);
}
for(int i=0;i<m.length;i++){
if(max==m[i]){
System.out.println((char)(i+'a'));
System.out.println(max);
break;
}
}
sc.close();
}
}
6.ASC
题目描述
代码解析
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
System.out.println(65+11);
scan.close();
}
}
7.递增三元组
题目描述
输入输出描述
输入输出样例
代码解析
自己写的暴力只能过67%。后面的代码用双指针。
import java.util.Arrays;
import java.util.Scanner;
//1:无需package
//2: 类名必须Main, 不可修改
public class Main {
static int count=0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
int n=sc.nextInt();
int []a=new int[n+1];
int []b=new int[n+1];
int []c=new int[n+1];
for(int i=0;i<n;i++){
a[i]=sc.nextInt();
}
for(int i=0;i<n;i++){
b[i]=sc.nextInt();
}
for(int i=0;i<n;i++){
c[i]=sc.nextInt();
}
Arrays.sort(a);
Arrays.sort(b);
Arrays.sort(c);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int k=0;k<n;k++){
if(a[i]<b[j]&&b[j]<c[k]){
count++;
}
}
}
}
System.out.println(count);
sc.close();
}
}
import java.util.Arrays;
import java.util.Scanner;
//1:无需package
//2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
int n=sc.nextInt();
int []a=new int[n];
int []b=new int[n];
int []c=new int[n];
for(int i=0;i<n;i++){
a[i]=sc.nextInt();
}
for(int i=0;i<n;i++){
b[i]=sc.nextInt();
}
for(int i=0;i<n;i++){
c[i]=sc.nextInt();
}
Arrays.sort(a);
Arrays.sort(b);
Arrays.sort(c);
int ai = 0, ci = 0;
long ans = 0L;
for (int i = 0; i < a.length; i++) {
while (ai < n && b[i] > a[ai]) ai++;
while (ci < n && b[i] >= c[ci]) ci++;
ans += 1L * ai * (n - ci);
}
System.out.println(ans);
}}
8.环境治理
问题描述
输入输出描述
样例输入输出及评测用例
代码解析
本来想着是对第一行和最后一列每天-1,然后统计(第一行+前n行最后一列的值)*2,如果<=q则输出。不知道哪里出错,运行不出来。摆烂了。
import java.util.Scanner;
//1:无需package
//2: 类名必须Main, 不可修改
public class 环境治理 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
long r=0;//用来统计第一行的值
long l=0;//用来统计前n行最后一列的值
long day=0;//所需最少天数
long sum=0;//灰尘度
int n=sc.nextInt();
long q=sc.nextLong();
long [][]a=new long[n][n];
long [][]b=new long[n][n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
a[i][j]=sc.nextLong();
}
}//输入整数
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
b[i][j]=sc.nextLong();
}
}//输入整数
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==0&&a[i][j]>b[i][j]&&i!=j){
a[i][j]-=1;
}//对第一行的数-1;
if(i!=0&&j>i&&i!=j&&a[i][j]>b[i][j]){
a[i][j]-=1;
}对除了第一行的数以及j>i,j!=i的数进行-1;
for(int k=1;k<n;k++){
r+=a[0][k];
l+=a[k][n-1];
//统计第一行和前n行最后一列的值
}
sum+=(r+l)*2;//统计全部灰尘度
if(sum>q){
day++;
}
if(sum<=q){
System.out.println(day);
return;
}
}
}
sc.close();
}
}
9.排列字母
问题描述
代码解析
import java.util.Arrays;
import java.util.Scanner;
//1:无需package
//2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
String str="WHERETHEREISAWILLTHEREISAWAY";
char []arr=str.toCharArray();
Arrays.sort(arr);
System.out.println(new String(arr) );
scan.close();
}
}
10.GCD
问题描述
输入输出格式
样例输入输出及评测样例
代码解析
公式
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
long a=sc.nextLong();
long b=sc.nextLong();
long x=Math.abs(a-b);
System.out.println(x-a%x);
sc.close();
}
public static int gcd(int n,int m){
return m==0?n:gcd(m,n%m);
}
}
11.选数异或
问题描述
输入输出格式
样例输入输出及评测样例
代码解析
import java.io.*;
import java.util.*;
public class _6选数异或 {
//暴力 -> 只能得到40%的分数了
//动态规划 ?? 哇,不是吧
//异或运算的规律 a^b=x 那么 a^x=b
static int N = (int)1e5+5; //开辟数组的最大空间
static int[] dp = new int[N]; //dp[i]:以[1:i]中左端点的最大索引,注意有状态的延续
//哈希表辅助我们更新dp数组
static Map<Integer, Integer> map = new HashMap<>(); //哈希表元素对应index索引
//修改之后
public static void main(String[] args) throws IOException { //需要抛出异常
Scanner sc = new Scanner(System.in);
// BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
st.nextToken(); //快速获取一个整数
int n = (int)st.nval;
st.nextToken();
int m = (int) st.nval; //m次查询
st.nextToken();
int x = (int) st.nval; //数组中的两个不同元素异或值为x a[i]^a[j]==x (i != j)
for (int i = 1; i <= n; i++){
st.nextToken();
int a = (int )st.nval; //接受我们需要判断的数组
dp[i] = Math.max(dp[i-1], map.getOrDefault(a^x, 0)); //如没有,就初始化为0,0小于任何的l,所有会自动输出no
map.put(a, i); //存储元素对应索引
}
//只用判断yes or no,类似于判断true or false,这类的判定性问题,还是要设计巧妙的method!
while(m-- > 0){
st.nextToken();
int l = (int) st.nval;
st.nextToken();
int r = (int) st.nval;
if (dp[r] >= l) {
System.out.println("yes");
}
else{
System.out.println("no");
}
}
}
}
12.灌溉
题目描述
输入输出描述
输入输出样例
代码解析
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class 灌溉BFS {
static int []X={0,0,-1,1};
static int []Y={1,-1,0,0};//用来表示上下左右
static int [][]map;
static int count;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();//输入n
int m=sc.nextInt();//输入m
int t=sc.nextInt();//输入水管数
count=t;//有多少个水管就表示有多少个被灌溉
int [][]XY=new int[t][2];//用来表示水管位置
for(int i=0;i<2;i++){
XY[i][0]=sc.nextInt();
XY[i][1]=sc.nextInt();
}
int k=sc.nextInt();//输入时间
map=new int[n][m];
Queue<int[]>queue=new LinkedList<>();//构造队列
for(int i=0;i<t;i++){
map[XY[i][0]-1][XY[i][1]-1]=1;//先将初始水管输入,标记为1
queue.offer(new int[]{XY[i][0]-1,XY[i][1]-1});//将水管入队
}
while(k>0&&!queue.isEmpty()){
k--;
int len=queue.size();//找到队列长度,循环进行出队操作
for(int i=0;i<len;i++){
int[] nums=queue.poll();//出队
int x=nums[0];//出队后新的一个点所在的行
int y=nums[1];//出队后新的一个点所在的列
for(int j=0;j<4;j++){
int newx=x+X[j];//对新的点接下来的操作进行遍历,也就是左右移动
int newy=y+Y[j];//对新的点接下来的操作进行遍历,也就是上下移动
if(newx < n&&newx >= 0&&newy < m&&newy >= 0){
if(map[newx][newy]==0){
count++;//如果操作后的点为0,即:没有被灌溉
map[newx][newy]=1;//操作后新的点已经被灌溉,所以对新的点赋值为1表示已被灌溉
queue.offer(new int[]{newx,newy});//重新对新的点入队然后进行相同的操作
}
}
}
}
}
System.out.println(count);
}
}
13.小朋友崇拜圈
题目描述
输入输出描述
样例输入输出
代码解析
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
int n=sc.nextInt();
int []arr=new int[n+1];
int len=0;
int maxlen=0;
for(int i=1;i<=n;i++){
arr[i]=sc.nextInt();
}
for(int i=0;i<n;i++){
len=dfs(arr,i,0);
if(maxlen<len){
maxlen=len;
}
}
System.out.println(maxlen);
sc.close();
}
public static int dfs(int[]arr,int i,int j){
int key=arr[i];
len++;
while(key!=i){
if(len>arr.length){
return 0;
}
key=arr[key];
len++;
}
return len;
}
}
14.纸张尺寸
问题描述
输入输出
样例输入输出
代码解析
简单是简单,想挺久的,还是太菜了。不过学到一个新的知识点:怎么键盘输入字符串数组,用split
import java.util.Scanner;
//1:无需package
//2: 类名必须Main, 不可修改
public class Main {
static int max=1189;
static int min=841;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
String str=sc.next();
String []arr=str.split("");
int len=Integer.parseInt(arr[1]);
for(int i=0;i<=9;i++){
int temp;
if(i<len){
max/=2;
if(max<min){
temp=max;
max=min;
min=temp;
}
}
}
System.out.println(max);
System.out.println(min);
sc.close();
}
}
15.最大数字
问题描述
输入输出格式
样例输入输出及评测样例
代码解析
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
static String str;
static long a;
static long b;
static long sum=0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
str=sc.next();
a=sc.nextLong();
b=sc.nextLong();
dfs(0,a,b,0);
System.out.println(sum);
}
public static void dfs(int i,long a,long b,long v){
if(i<str.length()){
long x=(long)(str.charAt(i)-'0');
long t=Math.min(a,9-x);
dfs(i+1,a-t,b,v*10+x+t);
if(b>x){
dfs(i+1,a,b-x-1,v*10+9);
}
}
else{
sum=Math.max(sum, v);
}
}
}
16.全排列的价值
问题描述
输入输出格式
样例输入输出及评测用例
代码解析
这道题主要是公式,公式不懂就写不出来,不过要是能推导出来也可以。
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
//递推公式dp[n]=dp[n-1]*n+i*(i-1)/2*全排列数量
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
int n=sc.nextInt();
long[]dp=new long[n+1];
long num=1;
long sum=1;
dp[0]=0;
dp[1]=0;
for(int i=2;i<=n;i++){
dp[i]=(dp[i-1]*(i)+num*sum)%998244353;
sum=(sum+i)%998244353;
num=(num*i)%998244353;
}
System.out.println(dp[n]);
sc.close();
}
}
17.灭鼠先锋
问题描述
代码解析
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
System.out.println("LLLV");
scan.close();
}
}
18.小蓝与钥匙
题目描述
答案提交
代码解析
错位排列递推公式 D(n)=(n-1)(D(n-1)+D(n-2))
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
static int N=14;
public static void main(String[] args) {
long f1=0;
long f2=1;
long temp=0;//错位排列地推公式D(n)=(n-1)(D(n-1)+D(n-2))
for (int i = 3; i <= 14; i++) {
temp=f2;
f2=(i-1)*(f1+f2);
f1=temp;
}
System.out.println(f2*40116600);//40116600为C14 28
}
}
19.李白打酒加强版
问题描述
输入输出格式
样例输入输出及样例评测
代码解析
.dp
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
//dp[n][m][k]表示遇见n店,m花,还剩k酒。
//因为题目要求最后一次必须是花,因此倒数第二次肯定剩余1数量的酒。
//所以答案ans = dp[n][m-1][1]。
//当剩余偶数酒的时候,有可能你上次遇见花也遇见店。
//当剩余奇数酒的时候,你上次必遇见店。
public class Main {
public static final int mod = (int)1e9+7;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int m=scan.nextInt();
int[][][] dp = new int[n+1][m+1][m+5];
dp[0][0][2]=1;
dp[0][1][1]=1;
dp[0][2][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
for(int k=0;k<=m;k++){
if(k%2==0){
//店或者花
if(j>0) dp[i][j][k]+=dp[i][j-1][k+1];
if(i>0) dp[i][j][k]+=dp[i-1][j][k/2];
}
else{
//店
if(j>0) dp[i][j][k]+=dp[i][j-1][k+1];
}
dp[i][j][k]%=mod;
}
}
}
System.out.println(dp[n][m-1][1]%mod);
scan.close();
}
}