2019年第十届蓝桥杯JAVAB组-----试题 J: 分考场

7 篇文章 0 订阅
7 篇文章 0 订阅

题目:

【问题背景】

古语有云:春风得意马蹄疾,一日看尽长安花。
当然在一场考试中所有人都春风得意马蹄疾是不可能的,尤其是碰到一些毒瘤出题人的时候。

【问题描述】

又到了每月一次的月考,又是 xf 老师出题。

上一次 xf 老师出的题太毒瘤了,平均分只有 40 多,同学们都非常不满意,毕竟别的科的平均分都是 80 多。

这次 xf 为了不被同学们寄刀片,想了一个办法:只公布所有考场的平均分的平均分。这样他就可以通过调整考场的分配方式,使得平均分显得高。(每个考场都可以容纳无限人)

每次考试也不是所有同学都参加的,只有学号在 [l,r] 这个区间中的同学会参加。

他想知道对于每次考试,他调整过考场后,所有考场的平均分的平均分的最大值。

当然,同学们也可能会努力学习或整日颓废使成绩发生改变。

【输入格式】

输入的第一行包含一个整数 n。

第二行包含 n 个整数,第 i 个数 vi,表示开始时每个同学的成绩。

第三行包含一个整数 q,表示有 q 次操作。

之后 q 行,每行描述一个操作,第一个数表示操作类型。

如果操作为 1 p x,表示学号为 p 的同学分数变为 x。

如果操作为 2 l r k, 表示把学号在 [l,r] 中的同学分成 k 个考场,求这 k 个考场的平均分的平均分的最大值。

【输出格式】

对于每个 2 操作输出一行,四舍五入保留正好 3 位小数。

【样例输入】

5
5 3 4 2 1
5
2 1 4 3
1 4 8
2 3 5 3
1 2 2
2 1 3 2

【样例输出】

3.833
4.333
4.000

【样例说明】

第一个操作询问学号在 [1, 4] 之间的同学分成 3 个考场的平均分的平均分的最大值,最优策略是:{1}, {2, 4}, {3},平均分是

在这里插入图片描述
第二个操作把学号为 4 的同学的分数变为 8。

第三个操作询问学号在 [3, 5] 之间的同学分成 3 个考场的平均分的平均分的最大值,最优策略是:{3}, {4}, {5}。

第四个操作把学号为 2 的同学分数变为 2。

第五个操作询问学号在 [1, 3] 之间的同学分成 2 个考场的平均分的平均分的最大值,最优策略是:{1}, {2 3}。

【评测用例规模与约定】

对于全部评测用列,n ≤ 200000, q ≤ 200000, 任意时刻同学的分数 vi ≤ 109,k ≤ r − l + 1。

评测时将使用 10 个评测用例测试你的程序,每个评测用例的限制如下:

在这里插入图片描述

 

题解:

首先肯定是分析,就是有一组同学这组同学有各自的成绩,然后给你几个操作,操作为1 的话是改变同学的成绩,操作为2的话就是在当前成绩(有可能已经修改过)下计算,把所有学生分为k组求所有组平均分的平均分最大值,就是每一个小组先求平均值,然后求小组的和,再求平均值,则最大的是多少,示例已经有了,5 3 4 2分3组怎么才能保证3组的平均数的和的平均数最大。

我的思路:

我是使用dfs的,全排列把所有的分法遍历一边,一个数组记录每个组的分数和,一个数组记录每个组分了几次,

例如: 一种:记录分数和:14,0,0  记录次数:4,0,0 

二种:记录分数和:12,2,0  记录次数:3,1,0

三种:记录分数和:8,6,0  记录次数:2,2,0

用一个max记录遍历所有情况中的最大值(是所有小组的平均值的和的平均值),最后输出max就是一次操作为2 时候的数值了。

后面就没有什么难度了,附上代码: (记得最后处理一下保留的小数)

package _2019_10;

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

public class Main {
	static int nums[];
	static int targetnums[];
	int numbers[];
	static double max=Integer.MIN_VALUE;
	public static void main(String[] args) {
		
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt();
		nums=new int[n+1];
		targetnums=new int[n+1];
		for (int i = 1; i <=n; i++) {
			nums[i]=scanner.nextInt();
		}
		int m=scanner.nextInt();
		String maxnums[]=new String[m];
		int index=0;
		for (int i = 0; i < m; i++) {
			int step=scanner.nextInt();
			if (step==1) {
				int num=scanner.nextInt();
				int core=scanner.nextInt();
				nums[num]=core;
			}else if (step==2) {
				int num1=scanner.nextInt();
				int num2=scanner.nextInt();
				int num3=scanner.nextInt();
				int numbers[]=new int[num3];
				int numbers2[]=new int[num3];
				dfs(num1,num2,numbers,numbers2);
				maxnums[index]=new DecimalFormat("0.000").format(max).toString();
				max=Integer.MIN_VALUE;
				index++;
			}
		}
		for (int i = 0; i < index; i++) {
			System.out.println(maxnums[i]);
		}
	}
	static void dfs(int num1,int num2,int numbers[],int numbers2[]) {
		if (num1>num2) {	
			double sumnums = 0;
			for (int i = 0; i < numbers.length; i++) {
				if (numbers2[i]!=0) {
					sumnums+=(double)numbers[i]/numbers2[i];
				}
			}
			sumnums=sumnums/numbers.length;
			if (sumnums>max) {
				max=sumnums;
			}else {
				return;
			}
			return;
		}
		for (int i = 0; i <numbers.length; i++) {
			numbers[i]+=nums[num1];
			numbers2[i]++;
			dfs(num1+1, num2, numbers,numbers2);
			numbers[i]-=nums[num1];
			numbers2[i]--;
		}
		
	}
}

结语:这样写的话数据量大的话绝对会超时,只是骗分操作吧,没有好思路只能骗分了

 

更新:去蓝桥云课官网那里提交竟然pass了,我还以为会超时

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值