选靓号——拼多多笔试题(贪心+暴力)

徘徊边缘 提交于 2019-12-25 01:00:20

题意

链接:https://www.nowcoder.com/questionTerminal/005af31a10834b3688911463065ab47d
来源:牛客网

A 国的手机号码由且仅由 N 位十进制数字(0-9)组成。一个手机号码中有至少 K 位数字相同则被定义为靓号。A 国的手机号可以有前导零,比如 000123456 是一个合法的手机号。
小多想花钱将自己的手机号码修改为一个靓号。修改号码中的一个数字需要花费的金额为新数字与旧数字之间的差值。比如将 1 修改为 6 或 6 修改为 1 都需要花 5 块钱。
给出小多现在的手机号码,问将其修改成一个靓号,最少需要多少钱?
输入描述:
第一行包含2个整数 N、K,分别表示手机号码数字个数以及靓号至少有 K 个数字相同。第二行包含 N 个字符,每个字符都是一个数字('0'-'9'),数字之间没有任何其他空白符。表示小多的手机号码。数据范围:2 <= K <= N <= 10000


输出描述:
第一行包含一个整数,表示修改成一个靓号,最少需要的金额。第二行包含 N 个数字字符,表示最少花费修改的新手机号。若有多个靓号花费都最少,则输出字典序最小的靓号。
示例1

输入

6 5
787585

输出

4
777577

说明

花费为4的方案有两种:777577与777775,前者字典序更小。

思路

枚举每个数字(0~9)作为目标相同数字i,慢慢扩展间隔gap,贪心策略,先处理i+gap,即比i大的,而且顺着替换,因为这样会让字典序变小;再处理i-gap,即比i小的,这里当存在的i-gap比需求need多时,要倒着遍历替换,因为正着会让字典序变大。

具体看代码,还是很简单的。

代码

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt(), k = in.nextInt();
		StringBuilder ss = new StringBuilder(in.next());
		int a[] = new int[10];
		for (int i = 0; i < n; i++) {
			a[ss.charAt(i) - '0']++;
		}
		int ans = 0x3f3f3f3f;
		StringBuilder res = new StringBuilder();
		for (int i = 0; i <= 9; i++) {
			int need = k - a[i], gap = 1, sum = 0;
			StringBuilder s = new StringBuilder(ss);
			// System.out.println(s);
			while (need > 0) {
				// System.out.println("gg");
				if (i + gap <= 9) {
					if (a[i + gap] < need) {
						for (int j = 0; j < n; j++) {
							if (s.charAt(j) - '0' == i + gap) {
								s.setCharAt(j, (char) (i+'0'));
							}
						}
						sum += gap * a[i + gap];
						need -= a[i + gap];
					} else {
						sum += gap * need;
						for (int j = 0; j < n; j++) {
							if (s.charAt(j) - '0' == i + gap && need > 0) {
								s.setCharAt(j, (char) (i+'0'));
								need--;
							}
						}

						break;
					}
				}
				if (i - gap >= 0) {
					if (a[i - gap] < need) {
						for (int j = 0; j < n; j++) {
							if (s.charAt(j) - '0' == i - gap) {
								s.setCharAt(j, (char) (i+'0'));
							}
						}
						sum += gap * a[i - gap];
						need -= a[i - gap];
					} else {
						sum += gap * need;
						for (int j = n - 1; j > 0; j--) {
							if (s.charAt(j) - '0' == i - gap && need > 0) {
								s.setCharAt(j, (char) (i+'0'));
								need--;
							}
						}

						break;
					}
				}
				gap++;
			}
			String st = s.toString();
			String rt = res.toString();
//			System.out.println(i+" "+sum+" "+s);
			if (sum < ans) {
				ans = sum;
				res = s;

			} else if (sum == ans && st.compareTo(rt) < 0) {
				res = s;
			}
		}
		System.out.println(ans);
		System.out.println(res);
	}
}

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!