第十四届蓝桥杯javaA组2024年省赛初赛题解_蓝桥杯特殊日期2408 题解

文章详细描述了几道编程题目的解题思路,涉及DFS搜索、动态规划、贪心算法、差分前缀和等技术,以及优先队列在旅行计划问题中的应用。
摘要由CSDN通过智能技术生成

**题意:**5个数从上往下,相邻的两个两两计算,运算符是&,或|,或^。已知这5个数,求多少种运算符情况可以最后答案是1

思路:dfs搜索,我的答案是:30528

dfs枚举所有运算符的排列情况,就是pow(3,10)=59049种,然后把这5个数从上往下计算,要是最后结果为1答案数+1。

代码(c++写的):

#include <bits/stdc++.h>
using namespace std;
int sum=0;
int a[100005];
int dp[10][10];
int mp[10][10];
void dfs(int d){
    if(d==11){
        for(int i=1;i<=4;i++) mp[1][i]=a[i];
        for(int i=1;i<=3;i++) mp[2][i]=a[i+4];
        for(int i=1;i<=2;i++) mp[3][i]=a[i+7];
        for(int i=1;i<=1;i++) mp[4][i]=a[10];
        for(int i=1;i<=4;i++){
            for(int j=1;j<=4-i+1;j++){
                if(mp[i][j]==0) dp[i][j]=dp[i-1][j]|dp[i-1][j+1];
                if(mp[i][j]==1) dp[i][j]=dp[i-1][j]^dp[i-1][j+1];
                if(mp[i][j]==2) dp[i][j]=dp[i-1][j]&dp[i-1][j+1];
            }
        }
        if(dp[4][1]==1)
            sum++;
        return;
    }
    a[d]=0;
    dfs(d+1);
    a[d]=1;
    dfs(d+1);
    a[d]=2;
    dfs(d+1);
}
int main()
{
    dp[0][1]=1;
    dp[0][2]=0;
    dp[0][3]=1;
    dp[0][4]=0;
    dp[0][5]=1;
    dfs(1);
    cout<<sum<<endl;
    return 0;
}

试题 C: 平均

**题意:**给若干个数(范围是0-9),和他们的更改的花费,求最小花费,使得0-9最终数量相同

思路:贪心

只将数量>n/10的数改为其他数,也就是数量>n/10要改掉 (数量-n/10)个。当然是找其中最小的改

通过:思路的时间复杂度可以100%,具体通过看情况

代码:

import java.util.*;
public class Main{
	public static void main(String[] args){
		Scanner cin =new Scanner(System.in);
		int n=cin.nextInt();
		int A[][]=new int[11][100005];
		int len[]=new int[15];
		for(int i=1;i<=n;i++) {
			int x=cin.nextInt();
			int y=cin.nextInt();
			A[x][++len[x]]=y;
		}
		for(int i=0;i<10;i++) 
			Arrays.sort(A[i],1,len[i]+1);    //排序,不用list是因为没有板子,手敲不出来
		long sum=0;
		for(int i=0;i<10;i++) {
			for(int j=1;j<=len[i]-n/10;j++) {
				sum+=A[i][j];
			}
			
		}
		System.out.println(sum);
	}
}


试题 D: 棋盘

**题意:**一个n*m的棋盘,开始全是白子,选择一个矩形全部反转,最后的棋盘情况打印一下

思路:差分前缀和

就是将这个矩形全部数+1(刚开始全是0),最后%2就是答案

因为最大数据也只是2000,每次在将要改变的行中,差分修改。总执行次数也不过是2000*2000。

最后逐行前缀和,打印这些数%2,注意打印时没有空格

通过:思路的时间复杂度可以100%,具体通过看情况

代码:

import java.util.*;
public class Main{
	public static void main(String[] args){
		Scanner cin =new Scanner(System.in);
		int n=cin.nextInt();
		int m=cin.nextInt();
		int A[][]=new int[2005][2005];
		for(int i=1;i<=m;i++) {
			int x1=cin.nextInt();
			int y1=cin.nextInt();
			int x2=cin.nextInt();
			int y2=cin.nextInt();
			for(int j=x1;j<=x2;j++) {
				A[j][y1]++;        //差分
				A[j][y2+1]--;
			}
		}
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=n;j++) {
				A[i][j]+=A[i][j-1];        //前缀和
				System.out.print(A[i][j]%2);
			}
			System.out.println();
		}
	}
}


试题 E: 互质数的个数

题意:1-pow(a,b)中有多少个数,和pow(a,b)互质

思路:思维+gcd+快速幂

答案就是pow(a,b-1)*r,r是1-a中和a互质的数量

和a*a*a*a…互质,就是和a互质的数。

a,b互质就是gcd(a,b)==1。而(a,b)和(a,b+a),和(a,b+a*2)…的互质情况是一样的,求gcd()那个公式应该能看出来

也就是有循环,只看1-a就行。而r就是欧拉函数

通过:

欧拉函数求可以100%

100%代码:

import java.util.*;
public class Main{
    static long mod=998244353;
    static long Euler(long n){        //求欧拉函数值
        long res=n;
        for(long i=2;i*i<=n;++i){
            if(n%i==0){
                res=res/i*(i-1);
                while(n%i==0)
                    n/=i;
            }
        }
        if(n>1)
            res-=res/n;
        return res;
    }
    static long qpow(long a,long b){
        long ans=1;
        while(b!=0){
            if(b%2==1)
                ans=ans*a%mod;
            a=a*a%mod;
            b/=2;
        }
        return ans;
    }
    public static void main(String[] args){
        Scanner cin =new Scanner(System.in);
        long a=cin.nextLong();
        long b=cin.nextLong();
        long r=Euler(a);        //1-a中有多少个数和a互质
        System.out.println(qpow(a,b-1)*(r%mod)%mod);
    }
}

试题 F: 阶乘的和

题意:

思路:这题没有比较好的思路。

只有用乘法求余公式,暴力计算最大的m。

ans=1,2,6,24,120…。计算这些阶乘的和是否是能被ans其整除,也就是判断:

A[1]!%ans+A[2]!%ans+…+A[n]!%ans==0

要是不行的话,就输出当前ans对应的阶乘数。

通过:

可以看到方法不一定能过前40%,但是大多情况下,也有可能过些

代码:

import java.util.*;
public class Main{
	public static void main(String[] args){
		Scanner cin =new Scanner(System.in);
		int n=cin.nextInt();
		int a[]=new int[n+10];
		for(int i=1;i<=n;i++) {
			a[i]=cin.nextInt();
		}
		long ans=1,p=1;
		while(true) {
			long sum=0;
			for(int i=1;i<=n;i++) {
				long res=1;
				for(int j=2;j<=a[i];j++) {
					res=res*j%ans;
				}
				sum=(sum+res)%ans;        //算和
			}
			if(sum==0) {
				ans*=(++p);
			}else {
				break;
			}
		}
		System.out.println(p-1);
	}
}

试题 G: 小蓝的旅行计划

思路:思维+优先队列

把前面的所有能买的单价和其数量记录下来,然后一旦没有油就从中去除最小的价格。

100%的思路应该是优先队列,存储长度为2的list,每次弹出最小价格,并修改其数量。一旦为0就不再压入。

根据评论,因为油箱有m的上限,所以这个思路不完全正确,具体我也想不到完全正确的思路了

通过:

优先队列,存储长度为2的list可以100%。

代码(优先队列按数量存60%):

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner cin =new Scanner(System.in);
        PriorityQueue q=new PriorityQueue();
        int n=cin.nextInt();
        int m=cin.nextInt();
        long sum=0;
        for(int i=1;i<=n;i++) {
            int x=cin.nextInt();
            int y=cin.nextInt();
            int z=cin.nextInt();
            m-=x;
            while(m<0) {
                if(q.isEmpty()) {
                    sum=-1;
                    i=n+1;
                    break;
                }
                int r=(int)q.poll();
                sum+=r;
                m++;
            }
            for(int j=1;j<=z;j++) {
                q.add(y);
            }
        }
        System.out.println(sum);
    }
}

代码(优先队列按序列存100%):

import java.lang.reflect.Array;
import java.util.*;
public class Main{
    static ArrayList fun(int x,int y){
        ArrayList<Integer> t=new ArrayList();
        t.add(x);
        t.add(y);
        return t;
    }
    public static void main(String[] args){
        Scanner cin =new Scanner(System.in);
        PriorityQueue<ArrayList<Integer>> q=new PriorityQueue<>(new Comparator<ArrayList<Integer>>(){
            @Override
            public int compare(ArrayList<Integer> a, ArrayList<Integer> b){
                return a.get(0)-b.get(0);
            }
        });
        int n=cin.nextInt();
        int m=cin.nextInt();
        long sum=0;
        for(int i=1;i<=n;i++) {
            int x=cin.nextInt();
            int y=cin.nextInt();
            int z=cin.nextInt();
            m-=x;
            while(m<0) {
                if(q.isEmpty()) {
                    sum=-1;
                    i=n+1;
                    break;
                }
                List<Integer> r=q.poll();       //前面价格最小的
                int res=Math.min(r.get(1),-m);      //这次使用r的数量
                sum+=(long)res*r.get(0);
                m+=res;
                if(res!=r.get(1))       //要是还有剩余,将剩余数量再加入q中
                    q.add(fun(r.get(0),r.get(1)-res));
            }
            q.add(fun(y,z));
        }
        System.out.println(sum);
    }
}


分享

首先分享一份学习大纲,内容较多,涵盖了互联网行业所有的流行以及核心技术,以截图形式分享:

(亿级流量性能调优实战+一线大厂分布式实战+架构师筑基必备技能+设计思想开源框架解读+性能直线提升架构技术+高效存储让项目性能起飞+分布式扩展到微服务架构…实在是太多了)

其次分享一些技术知识,以截图形式分享一部分:

Tomcat架构解析:

算法训练+高分宝典:

Spring Cloud+Docker微服务实战:

最后分享一波面试资料:

切莫死记硬背,小心面试官直接让你出门右拐

1000道互联网Java面试题:

Java高级架构面试知识整理:

形式分享:**

(亿级流量性能调优实战+一线大厂分布式实战+架构师筑基必备技能+设计思想开源框架解读+性能直线提升架构技术+高效存储让项目性能起飞+分布式扩展到微服务架构…实在是太多了)

其次分享一些技术知识,以截图形式分享一部分:

Tomcat架构解析:

[外链图片转存中…(img-SBXrQyQc-1714778573041)]

算法训练+高分宝典:

[外链图片转存中…(img-vdz83pRG-1714778573041)]

Spring Cloud+Docker微服务实战:

[外链图片转存中…(img-swZe6Y9K-1714778573041)]

最后分享一波面试资料:

切莫死记硬背,小心面试官直接让你出门右拐

1000道互联网Java面试题:

[外链图片转存中…(img-ffuPHD7V-1714778573042)]

Java高级架构面试知识整理:

[外链图片转存中…(img-Eqcv4jZu-1714778573042)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2022蓝桥杯Java A是中国著名的计算机竞赛之一,该比赛旨在发掘和培养优秀的Java程序设计人才。参赛者需要具备一定的Java编程基础和算法思维能力,通过解决一系列实际问题来展示自己的技术水平。 蓝桥杯Java A比赛内容将涉及Java语言基础知识、面向对象编程、数据结构与算法、数据库等方面。参赛选手需要通过模拟真实的工作场景,设计和实现各种功能模块,展现出自己解决问题的能力和代码的优雅性。 蓝桥杯Java A比赛对于参赛者来说是一次难得的锻炼机会。通过参加比赛,可以学习到实际项目中常用的技术和解决问题的思路,提高自己的编程能力。同时,这也是一个展示自己才华和与其他选手竞争的舞台,可以通过与其他优秀选手的交流互动,拓宽自己的视野,并且与同龄人一起追求计算机编程的进步。 参加蓝桥杯Java A比赛,不仅可以提升自己的技术能力,还能为自己的未来发展增加一份宝贵的竞赛经验。很多优秀的程序员和企业都非常看重蓝桥杯的参赛者,因为这代表着他们在编程领域具备一定的实力和潜力。 总而言之,参加2022蓝桥杯Java A是一个对自己实力的检验和提高的机会,同时也是一个与其他优秀选手竞争的平台,可以通过比赛锻炼自己的技术能力和解决问题的能力。参赛者在比赛中要保持冷静和耐心,学会与其他选手交流和合作,相信通过努力,一定能够在比赛中取得好的成绩。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值