最小移动数

来源:互联网 发布:数据分析挖掘与r语言 编辑:程序博客网 时间:2024/05/20 21:22

第五题:最小移动数

     康师傅在某一城市拥有自己的饭店,有N个伙计,每个伙计有自己的薪水。第i个伙计的薪水等于Wi(i=1, 2, ..., N)。康师傅想使所有伙计的薪水都相等。他的做法是:选定一个伙计,保持这个伙计的薪水不动,而给其它的伙计的薪水增加1个单位。换句话说,选定的伙计是一个倒霉蛋儿,他是唯一的一个在此操作中没有被增加薪水的人。但是,倒霉蛋伙计可以在不同的操作中是不同的人。康师傅可以使用这一操作任意多次,只要他愿意。但是他是一个大忙人,因此他想最小化总操作数,以最终达到所有人都平等的目标。你的任务是找到这一数值。

输入:

    输入的第一行包含一个整数T,代表所有的测试用例数。T个测试实例的详细描述跟随其后。每个测试实例的第一行包含唯一的一个整数N,代表所有的伙计数。第二行则包含空格分开的N个整数W1,W2,...,WN代表员工的薪水。

输出:

    对每一个测试实例,输出单一的一行,仅包含所有伙计达到平等所需的最小操作数。

约束:

   1 ≤ T ≤ 100

   1 ≤ N ≤ 100

   0 ≤ Wi ≤ 10000

样例输入:

2

3

1 2 3

2

42 42

样例输出:

3

0

运行时间限制:20

提示:本题如果以一种等价的方式来思考就会比较容易。给除一名员工之外所有员工工资增加1,等价于,给这名员工工资先减1,然后给所有员工工资都增加1。顺着这个思路继续深入下去,此题可解。

程序源码:

import java.util.Scanner;

public class Demo5 {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  // 从标准输入读取参数
  Scanner scanner = new Scanner(System.in);
  // 首先读取用例数
  String input = scanner.nextLine();
  String str[];
  int items[];
  int count = Integer.parseInt(input.trim());
  for (int i = 0; i < count; i++) {
   input = scanner.nextLine();
   int numbers = Integer.parseInt(input.trim());
   items = new int[numbers];
   input = scanner.nextLine();
   str = input.split(" ");
   for (int j = 0; j < str.length; j++) {
    items[j] = Integer.valueOf(str[j]);
   }
   java.util.Arrays.sort(items);
   int sum = 0;
   while (true) {
    int max = items[numbers - 1];
    if (max == items[0]) {
     break;
    }
    max = max - 1;
    items[numbers - 1] = max;
    for (int m = 0; m < numbers - 1; m++) {
     if (max < items[m]) {
      for (int j = numbers - 1; j > m; j--) {
       items[j] = items[j - 1];
      }
      items[m] = max;
      break;
     }
    }
    sum++;
   }
   System.out.println(sum);
  }
 }
}