2020年第11届蓝桥杯国赛javaC组

6.2020国赛javaC组

https://blog.csdn.net/qq_43449564/article/details/109841937

https://blog.csdn.net/imreal_/article/details/114272929

https://www.dtmao.cc/news_show_375163.shtml

C 扩散

import java.util.LinkedList;
import java.util.Queue;
//定义每一个点,记录坐标和它是经过多少步到达的
class Node{
	int x,y,step;
}
public class 扩散 {
	//声明n1和n2两个变量
	static Node n1,n2;
	//记录点是否被访问过
	static boolean flag;
	static int N = 6200;
	static boolean[][] book = new boolean[N][N];
	//定义方向,上,下,右,左
	static int[][] dirs = {
			{-1,0},
			{1,0},
			{0,1},
			{0,-1}
	};
	//定义队列,offer():压栈,poll():出栈,peek():返回队顶的元素,但不删除
	static Queue<Node> queue = new LinkedList<Node>();
	//初始就4个点
	private static int ans = 4;
	public static void main(String[] args) {
		//初始化原始的四个点
		//而本题是在一个画布上无限的扩散,
		//所以是没有边界的,故我们要在二维数组上加上2020即可。
		init(2020,2020);
		init(4040,2031);
		init(2031,2034);
		init(4020,4020);
		//开始广搜
		bfs();
		System.out.println(ans);
	}
	private static void bfs() {
		//队列中的元素不为空
		while (!queue.isEmpty()) {
			//取出并删掉队列头元素,以这个点的视角进行判断
			n1 = queue.poll();
			//如果取出的点已经是第2020分钟后的,直接结束广搜
			if (n1.step == 2020) {
				break;
			}
			//进行四个方向的选择
			for (int i = 0; i < 4; i++) {
				//新建节点
				n2 = new Node();
				n2.x =n1.x+dirs[i][0];
				n2.y =n1.y+dirs[i][1];
				//在当前节点的步骤上+1步,第2020分钟后,叫变成+2020
				//这代表了n2的step值是2020
				n2.step = n1.step+1;
				//这个点没被访问过,而且还没有到第2020步
				if (n2.step <=2020 &&!book[n2.x][n2.y]  ) {
//					System.out.println(n2.x+":"+n2.y);
					//标记这个点被访问过了
					book[n2.x][n2.y] = true;
					ans++;
					queue.offer(n2);
				}
			}	
		}	
	}
	private static void init(int x, int y) {
		book[x][y] = true;
		n1  = new Node();
		n1.x = x;
		n1.y = y;
		n1.step = 0;
		queue.offer(n1);
		
	}
}

D阶乘约数

  • 本题考查约数个数定理
import java.math.BigInteger;

public class 阶乘约数 {
   public static void main(String[] args) {
        BigInteger num = BigInteger.ONE;
        //算出100阶乘的值
        for (int i = 1; i <= 5; i++)
            num = num.multiply(new BigInteger(String.valueOf(i)));
        long res = 1;
        //从2开始,知道i*I>num为止
        for (BigInteger i = new BigInteger("2"); i.multiply(i).compareTo(num) <= 0; i = i.add(BigInteger.ONE)) {
            long cnt = 1;
            //约数个数定理
            //num%i == 0,是约数,然后执行while语句
            /*
		             例题:正整数378000共有多少个正约数?
		解:将378000分解质因数378000=2^4×3^3×5^3×7^1
		由约数个数定理可知378000共有正约数(4+1)×(3+1)×(3+1)×(1+1)=160个。
             */
            while (num.mod(i).compareTo(BigInteger.ZERO) == 0) {
            	
            	 num = num.divide(i);
                 cnt++;
            }
            if (cnt > 1)
                res *= cnt;
        }
        if (num.compareTo(BigInteger.ONE) > 0) res <<= 1;
        System.out.println(res);
    }

}

E: 本质上升序列

https://blog.csdn.net/m0_51955470/article/details/115706911

https://blog.csdn.net/qq_44443766/article/details/111601650

https://blog.csdn.net/u013098139/article/details/117150847

设str为题目中的目标字符串,定义dp[i]为以str[i]为结尾时的递增子序列的个数。
考虑j<i,遍历j=0~i-1,则有如下讨论:

str[j] < str[i],此时dp[i]=dp[i]+dp[j]
str[j] = str[i],此时dp[i]=dp[i]-dp[j]
str[j] > str[i],此时是降序,不考虑
为了观察方便,就以数字2、1、3、8、5、7、4、5为例:

package 国赛2020C组;

public class 本质上升子序列 {
	public static void main(String[] args) {
		//一个动态规划的题目
		String string = 
				 "tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhfiadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqijgihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmadvrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl";
	    int result = 0;
	    
		long ans = 0;
		//声明一个数组,里面的的值全为1
		int dp[] = new int[string.length()];
		for (int i = 0; i < dp.length; i++) {
			dp[i] = 1;
		}
		//每一个都遍历
		for (int i = 0; i < dp.length; i++) {
			
			for (int j = 0; j < i; j++) {
				if (string.charAt(j) < string.charAt(i)) {
					dp[i] = dp[i]+dp[j];
				}else if(string.charAt(j) == string.charAt(i)) {
					dp[i] = dp[i]-dp[j];
				}
			}
		}
		
		for (int i = 0; i < dp.length; i++) {
			ans += dp[i];
		}
		
		System.out.println(ans);
	}
}

F 天干地支

import java.util.Scanner;

public class 天干地支 {
	static String[] tiangan = {"jia","yi","bing","ding","wu","ji","geng","xin","ren","gui"};
	static String[] dizhi = {"zi","chou","yin","mao","chen","si","wu","wei","shen","you","xu","hai"};
	
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
//		以2020为基准算一下偏移量就行
		System.out.print(tiangan[(n + 6)% 10]);
        System.out.print(dizhi[(n - 4) % 12]);
	}
}

G皮亚诺曲线距离

https://www.cnblogs.com/valk3/p/14036850.html

H 蓝肽子序列

https://blog.csdn.net/hrn1216/article/details/51534607

public class 蓝肽子序列 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        char [] s1=scanner.nextLine().toCharArray();
        char [] s2=scanner.nextLine().toCharArray();
        int len1=s1.length;
        int len2=s2.length;
        int [][]dp=new int[len1+1][len2+1];
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
//            	元素相同时
                if(s2[j-1]==s1[i-1])
                {
//                	这个元素等于左上角的值
                    dp[i][j]=dp[i-1][j-1];
//                  当这个元素为大写的时候,才+1,也就是算一个
                    if('A'<=s2[j-1]&&s2[j-1]<='Z') dp[i][j]++;
                }
//            	元素不相同    
                else
                {
//                	把上面和左面的最大值赋给
                    if(dp[i-1][j]>=dp[i][j-1])
                    	dp[i][j]=dp[i-1][j];
                    else dp[i][j]=dp[i][j-1];
                }
            }
        }
        System.out.println(dp[len1][len2]);
    }
}

I 画廊

import java.text.DecimalFormat;
import java.util.Scanner;

public class 贪心 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		DecimalFormat fmt = new DecimalFormat("#.00");
		// long n = sc.nextLong();
		int l = sc.nextInt();
		int r = sc.nextInt();
		int d = sc.nextInt();
		int w = sc.nextInt();
//		左右画廊
		int[] la = new int[l];
		int[] ra = new int[r];
//   	左面赋值
		for (int i = 0; i < l; ++i) {
			la[i] = sc.nextInt();
		}
//		右面赋值
		for (int i = 0; i < r; ++i) {
			ra[i] = sc.nextInt();
		}
//      表示走完了第几个
		int li = 0;
		int ri = 0;
//		求出中间点
		double sx = (double) w / 2;
		double sy = 0.0;
//		这是总的距离
		double dist = 0;
//		没要找到所有的作品,就一直循环
		while (li < l || ri < r) {
//			人到作品的距离
			double ld = Double.MAX_VALUE, rd = Double.MAX_VALUE;
//			如果左面的作品没找完
			if (li < l) {
//				这里是以左边作为y轴,所以x的方向为01
				double x = sx - 0;
//				负负得正
				double y = sy - la[li];
				ld = Math.sqrt(x * x + y * y);
			}
//			右面的作品没找完
			if (ri < r) {
//				直接求出-w,然后负负得正
				double x = sx - w;
				double y = sy - ra[ri];
				rd = Math.sqrt(x * x + y * y);
			}
//			比较到左面和到右面的距离
			if (ld < rd) {
//				到左面近
//				记录距离
				dist += ld;
//				跟新y的坐标
				sy = la[li];
//				x坐标移到左面
				sx = 0;
				++li;
			} else {
//				到右面近
				dist += rd;
				sy = ra[ri];
//				
				sx = w;
				++ri;
			}
		}
		
		
//			这时已经到了最后一个作品,然后求出到终点的距离
			double x = sx - (double) w / 2;
			double y = sy - d;
			dist += Math.sqrt(x * x + y * y);
		

		System.out.println(fmt.format(dist));

	}
}

J 答疑

import java.util.Arrays;
import java.util.Scanner;
/*
3
10000 10000 10000
20000 50000 20000
30000 20000 30000

Output:
 */
public class 答疑 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
//		这里是每个人的数据
		Task[] tasks = new Task[n];
//		存贮着发消息的时刻
		long[] arr = new long[n];
		int s,a,e;
		long ans = 0,tem = 0;
		for (int i = 0; i < tasks.length; i++) {
			s = scanner.nextInt();
			a = scanner.nextInt();
			e = scanner.nextInt();
			tasks[i] = new Task(s, a, e);
		}
//		按照排序规则,进行排序
		Arrays.sort(tasks);
//		发消息时刻的存贮
		for (int i = 0; i < tasks.length; i++) {
			tem += tasks[i].sum;
			arr[i] = tem- tasks[i].e;
		}
//		最终答案的获取
		for (int i = 0; i < tasks.length; i++) {
			ans += arr[i];
		}
//		
//		for (int i = 0; i < arr.length; i++) {
//			System.out.println(arr[i]);
//		}
		System.out.println(ans);
	}
}

class Task implements Comparable<Task>{
	int s,a,e,sum;
//	这里的sum是这三个数的和,并以此来进行排序,看一个人的耗时小,就往前
	public Task(int s, int a, int e) {
		super();
		this.s = s;
		this.a = a;
		this.e = e;
		this.sum = this.s+this.a+this.e;
	}
	
	@Override
	public String toString() {
		return "Task [s=" + s + ", a=" + a + ", e=" + e + "]";
	}
	@Override
	public int compareTo(Task o) {
//如果总耗时相同,就比较回答时间的长短
		if (this.sum == o.sum ) 
			return this.e - o.e;
		return this.sum - o.sum;
	}
}

7.2020国赛javaB组

E 玩具蛇

public class 玩具蛇 {
//	默认都是false
    static boolean [][] key=new boolean[5][5];
//    四个方向的移动 上,下,左,右
    static int [][]move={{-1,0},{1,0},{0,-1},{0,1}};
    static int ans=0;
    
    public static void main(String[] args) {
        for (int i = 1; i <= 4; i++) {
            for (int j = 1; j <= 4; j++) {
//            	开始点变为ture
                key[i][j]=true;
                dfs(i,j,1);
                key[i][j]=false;
            }
        }
 
        System.out.println(ans);
    }
    /**
     * 
     * @param x
     * @param y
     * @param cur 代表是第走的步数,到了16步,就终止
     */
    private static void dfs(int x,int y,int cur)
    {
//    	终点判断
        if(cur==16)
        {
            ans++;
            return;
        }
//        朝着四个方向移动  上,下,左,右
        for (int i = 0; i < move.length; i++) {
            int x2=x+move[i][0];
            int y2=y+move[i][1];
            /**
            要去的点并没有超过临界值,并且没有被访问,那就就说明访问的点是合格的
             */
            if(x2>=1&&x2<=4&&y2>=1&&y2<=4&&!key[x2][y2])
            {
//            	将合格的点标记为访问过的
                key[x2][y2]=true;
//                在这个点的基础上,在进行选择
                dfs(x2,y2,cur+1);
//               说明这个点应经不是合格的点了,或者说已经到了终点了
//                需要回退,然后换个方向进行
                key[x2][y2]=false;
            }
        }
    }
}

I: 补给

https://blog.csdn.net/weixin_45640260/article/details/110252819

J 质数行者

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
/*
5 6 1
3 4 1 1 2 1


 */
public class 质数行者 {
	static int n,m,w;
	static int r1,c1,h1,r2,c2,h2;
//	存放着质数点
	static List<Integer> prime;

	static int[][][] dp ;
	static long Mood = 1000000007;
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		n = scanner.nextInt();
		m = scanner.nextInt();
		w = scanner.nextInt();
		r1 = scanner.nextInt();
		c1 = scanner.nextInt();
		h1 = scanner.nextInt();
		r2 = scanner.nextInt();
		c2 = scanner.nextInt();
		h2 = scanner.nextInt();
		prime = new ArrayList<Integer>();
//		所有dp的值都是-1
		dp = new int[n+1][m+1][w+1];
		   for (int i = 1; i <= n; i++)
	            for (int j = 1; j <= m; j++)
	            	 Arrays.fill(dp[i][j], -1);
//	   两个陷阱的值为0
		dp[r1][c1][h1] = 0;
		dp[r2][c2][h2] = 0;
//		访问过的值为1
		dp[1][1][1] = 1;
//		得到所有可行的质数
		int tem = Math.max(n, m);
		tem = Math.max(tem, w);
		int j;
		for (int i = 2; i <= tem ; i++) {
			for ( j = 2; j <= (int)Math.sqrt(i); j++) {
				if (i%j == 0) {
					break;
				}
			}
			
			if (j> (int)Math.sqrt(i)) {
				prime.add(i);
			}
		}
	

//	    开始递归,这个点也就是要去的点
		System.out.println(dfs(n,m,w));
	}

	private static long dfs(int x, int y, int z) {
//		这个点被访问或者说是陷阱
		if (dp[x][y][z] >= 0) {
			return dp[x][y][z] ;
		}

		
		long res = 0;
//		对所有质数进行遍历
		for (int i = 0; i < prime.size(); i++) {
//			if的判断,决定了是否越界
			if (x - prime.get(i) > 0) {
//				去下一个点
				res = (res+dfs(x-prime.get(i), y, z))%Mood;
			}
			
			if (y - prime.get(i) > 0) {
				res = (res+dfs(x, y-prime.get(i), z))%Mood;
			}
			
			if (z - prime.get(i) > 0) {
				res = (res+dfs(x, y, z-prime.get(i)))%Mood;
			}
		}
		
//		到了这里,递归已经完成了,这个点将被表记为访问过
		System.out.println(dp[x][y][z] = (int) res);
		return dp[x][y][z] = (int) res;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值