贪心算法练习day1

练习1--翻硬币

1)题目及要求

贪心算法练习day1_第1张图片

贪心算法练习day1_第2张图片

2)解题思路

输入的是字符串,要想将两组字符串进行一一对比,需要将字符串转换成字符数组,再使用for循环依次遍历字符数组,进行比对。

输入两行字符串,转换成两个字符数组;将初始数组和目标数组进行逐个对比,运用三目运算符进行判断

3)详细代码

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        String origin=scan.next();
        String target=scan.next();
        char[] originLine=origin.toCharArray();
        char[] targetLine=target.toCharArray();
        int result=0;
        for(int i=0;i

4)本题核心

 if(originLine[i]!=targetLine[i]){
            originLine[i]=originLine[i]== '*'?'o':'*';
            originLine[i+1]=originLine[i+1]== '*'?'o':'*';
            result++;
          }

练习2--付账

1)题目及要求

贪心算法练习day1_第3张图片

2)解题思路

让每个人尽可能付接近平均金额的钱数

根据金额和人数计算平均金额;对每个人的钱数进行从小到大排序;遍历排序后,将钱数少于平均金额的人 全部支付,再从总金额里减去该人所支付的金额;重新计算平均金额,剩余金额/剩余人数,同样钱数少于新平均金额的人也全部支付;最后钱最多的人支付剩余的。以此类推

3)详细代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;

/**
 * 贪心:为了使得标准差最小,每一个出的钱bi必须接近平均值s/n
 * [1]第i个人带的钱不够平均数avg,那么他只能出自己全部的钱ai
 * [2]第i个人带的钱比平均数avg多,那么他可以多付一些。
 *
 * 基本步骤如下:
 * 1、对ai从小到大排序
 * 2、排序后前一部分人的钱不够,那么就出他们所有的钱
 * 3、从总付钱数中扣除前一部分人出的钱,得剩余需要出得钱数为S',
 * 以及剩余得后一部分人的出钱平均数avg'
 * 4、后一部分人的钱多,他们多出一些:
 * (1)比较有钱的,但是他的钱也不够avg',那么他的钱也是全部出
 * (2)非常有钱的,不管怎么付他都有富余
 */
public class Main {
    public static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    public static void main(String[] args) throws IOException {
        int n = nextInt();
        long s = nextLong();
        long[] a = new long[n];

        //每个人带的钱数
        for (int i = 0; i 

4)本题核心

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.util.Scanner;  
  
public class Main {  
    public static void main(String[] args) throws IOException {  
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));  
        Scanner scanner = new Scanner(br);  
  
        int n = scanner.nextInt();  
        long s = scanner.nextLong();  
        long[] a = new long[n];  
  
        for (int i = 0; i < n; i++) {  
            a[i] = scanner.nextLong();  
        }  
  
        // ... (其余代码逻辑保持不变)  
    }  
}
  1. 输入和初始化

    • 通过StreamTokenizerBufferedReader从标准输入读取数据。
    • nextInt()nextLong()方法用于读取整数和长整数。
    • 初始化变量n(人数)、s(总金额需求)和a数组(每个人持有的钱)。
  2. 排序

    • 使用Arrays.sort(a)a数组进行排序,以确保从小到大的顺序。这是贪心策略的一部分,因为我们希望先使用钱较少的人来尽量接近平均值。
  3. 计算平均值

    • 计算总需求s的平均值avg
  4. 贪心选择

    • 遍历排序后的a数组。对于每个人,我们检查他们是否有足够的钱来支付平均值。
      • 如果某人的钱不足以支付平均值(即a[i] * (n - i) < s),那么他们会把所有的钱都拿出来。此时,我们更新总需求s,并计算这个人与平均值的差的平方,累加到sum中。
      • 如果某人的钱足够支付平均值,那么他们会支付平均值的金额,而后面的所有人也都能至少支付这个金额。因此,我们计算当前平均值与总平均值的差的平方,并乘以剩余的人数(n - i),然后累加到sum中。之后,我们跳出循环,因为没有必要再检查后面的人。
  5. 计算标准差

    • 使用公式Math.sqrt(sum / n)计算标准差,并保留四位小数后输出。这里,sum是每个人与平均值的差的平方的总和,而n是人数。标准差是衡量这组数分布离散程度的指标。

你可能感兴趣的:(贪心算法,算法)