1276: 峰峰不搞G

题目

  给 n 数量的油漆,写出最大的数,每个数对应有油漆的花费。更多内容点击标题。

分析

  我读完题,就想到用动态规划,结果是Time Limit Exceed。然后看了看提交,别人的代码都很短,我就想到应该是有规律的。

  这道题目的问题是计算出最大的数,我们就要考虑什么样的数最大,显然位数越多,数肯定越大。在Simple Input中的第一组数据中,你肯定愿意写5个5(55555),而不是2个6(66),就是这个道理。

  那如果是下面这组数据呢?你该怎么办?

36
11 12 13 45 78 46 51 45 84

  你会发现,可以写3个1(111),或者3个2(222),但是正确结果应该是 321 。因此,我的方法是先用油漆写出最长位数并且花费油漆最少的数,即 111,然后再用多出来的 3 个油漆检查是不是能够增加数。从前往后检查 111 , 从9-1判断。步骤如下:

数:111		剩余油漆:3
84比11多73,剩余的油漆不够写数字9
45比11多34,剩余的油漆不够写数字8
......
13比11多2,因此可以将第一个数字1变成3,数:311 剩余油漆:1
84比11多73,剩余的油漆不够写数字9
......
13比11多3,剩余的油漆不够写数字3
12比11多1,因此可一将第二个数字变成2,数:321 剩余油漆0
第三轮,剩余的油漆不能写任何比1大的数,因此最终结果为321。

  上述大意就是,先用一定油漆写出位数最长并且使用油漆最少的数,再将多余的油漆检查是否能将数中的最高位的数字替换成更大的数字。直到最后一位数字或者无较大可替换的数字为止。

  这里提供几组测试数据,毕竟题目给的三组数据有点少,仅供参考。

36
11 12 13 45 78 46 51 45 84
1
1 1 1 1 1 1 1 1 1
2
1 1 1 1 1 1 1 1 1
17
50 40 80 61 7 19 54 48 8
17
50 40 80 61 7 19 54 9 8

  正确结果是:

321
9
99
99
99

  直接看代码吧,调试更容易看懂。

代码

/**
* time 252ms
* @author PengHao
* @version A3.1
* @date 2019-04-21 上午9:44:18
*/ import java.util.Scanner; public class Main { private Scanner sc;
private int n; // 买的油漆数量
private int[] tab; // 每个数字对应的油漆数量
private String maxNum; // 能写出的最大的数值
private int maxLen; // 能写出的数值的最大长度
private int maxIndex; // 写出最长数值且用料最少的数字的下标 public Main() {
sc = new Scanner(System.in);
tab = new int[10]; // 下标从1开始
while (sc.hasNext()) {
input();
findMaxLen();
if (0 == maxLen) { // 一个数字都不能写
System.out.println("Lihun!");
continue; // 下一组数据
}
initMaxNum();
increase();
System.out.println(maxNum); // 输出
}
sc.close();
} /**
* Input data
*/
private void input() {
n = sc.nextInt();
for (int i = 1; i <= 9; i++) {
tab[i] = sc.nextInt();
}
} /**
* Set the <b>maxLen</b> and <b>maxIndex</b>
*/
private void findMaxLen() {
maxLen = maxIndex = 0;
for (int i = 9; i > 0; i--) {
if (n / tab[i] > maxLen) { // 第i个数字能写出的位数比maxLen还多
maxIndex = i;
maxLen = n / tab[maxIndex];
} else if (n / tab[i] == maxLen) { // 写出的位数相同
if (tab[i] < tab[maxIndex]) { // 看哪个数字用的油漆少
maxIndex = i; // 写用的油漆少的那个数字
}
}
}
} /**
* Initialize <b>maxNum</b>
*/
private void initMaxNum() {
maxNum = "";
// 将最大长度得到的数值赋给结果
for (int i = 0; i < maxLen; i++) {
maxNum += maxIndex;
}
} /**
* Substituting some Numbers makes the result bigger
*/
private void increase() {
int left = n % tab[maxIndex]; // 写出了maxNum后剩下的油漆
int j;
String small, big;
// 已经写出的数值的每一位检查一遍,看能不能替换成更大的数字
for (int i = 0; i < maxLen; i++) {
j = 9; // 从9开始
// 因为可能有两个数字需要同样多的油漆,因此left可以等于0
// 如果数字j比已经写出的数字还小就不用替换了,那样只会使得结果更小
while (left >= 0 && j > maxIndex) {
if (left >= tab[j] - tab[maxIndex]) { // 剩余的油漆可以使得写出的数字更大
small = String.valueOf(maxIndex);
big = String.valueOf(j);
maxNum = maxNum.replaceFirst(small, big);
left -= tab[j] - tab[maxIndex]; // 剩余油漆变少
break; // 第i个数字已经替换,直接退出找下一位
}
j--; // 先写较大的数字,因此这里是减
}
}
} public static void main(String[] args) {
new Main();
} }

写在最后:

  1. 如需转载,请于标题下注明链接形式的wowpH的博客即可;
  2. 代码原创,如需公开引用,不能删除首行注释(作者,版本号,时间等信息)。
  3. 如果有疑问欢迎评论留言,尽力解答。

WUSTOJ 1276: 峰峰不搞G(Java)的更多相关文章

  1. 500 G JAVA视频网盘分享(JEECG开源社区)

    500 G JAVA视频网盘分享(JEECG开源社区)   [涵盖从java入门到深入架构,Linux.云计算.分布式.大数据Hadoop.ios.Android.互联网技术应有尽有]   [转载:h ...

  2. 几周内搞定Java的10个方法

    不要将Java与JavaScript弄混了,Java的目标是“一次编译,到处调试”(呃,不对,是“到处运行”).简单来说,就是Java程序可以直接在任何设备上运行. Java语言是什么? 不管我们是否 ...

  3. 一文彻底搞懂Java中的环境变量

    一文搞懂Java环境变量 记得刚接触Java,第一件事就是配环境变量,作为一个初学者,只知道环境变量怎样配,在加上各种IDE使我们能方便的开发,而忽略了其本质的东西,只知其然不知其所以然,随着不断的深 ...

  4. 一个例子搞清楚Java程序执行顺序

    当我们new一个GirlFriend时,我们都做了什么? 一个例子搞懂Java程序运行顺序 public class Girl { Person person = new Person("G ...

  5. 一分钟搞定Java高频面试题

    一分钟搞定Java高频面试题 一.变量赋值和计算 题目: public static void main(String[] args) { int i = 1; i = i++; int j = i+ ...

  6. 一文搞懂Java引用拷贝、浅拷贝、深拷贝

    微信搜一搜 「bigsai」 专注于Java和数据结构与算法的铁铁 文章收录在github/bigsai-algorithm 在开发.刷题.面试中,我们可能会遇到将一个对象的属性赋值到另一个对象的情况 ...

  7. 一文搞懂Java引用拷贝、深拷贝、浅拷贝

    刷题.面试中,我们可能会遇到将一个对象的属性赋值到另一个对象的情况,这种情况就叫做拷贝.拷贝与Java内存结构息息相关,搞懂Java深浅拷贝是很必要的! 在对象的拷贝中,很多初学者可能搞不清到底是拷贝 ...

  8. 轻松搞懂Java中的自旋锁

    前言 在之前的文章<一文彻底搞懂面试中常问的各种“锁”>中介绍了Java中的各种“锁”,可能对于不是很了解这些概念的同学来说会觉得有点绕,所以我决定拆分出来,逐步详细的介绍一下这些锁的来龙 ...

  9. 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!

    本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...

随机推荐

  1. spring bean 的作用域之间有什么区别

    spring bean 的作用域之间有什么区别? spring容器中的bean可以分为五个范围.所有范围的名称都是说明的, 1.singleton:这种bean范围是默认的,这种范围确保不管接受到多个 ...

  2. react组件中返回并列元素的方法

    我们在写react组件的时候,经常会遇到这种问题,在render中return元素只能有一个顶级元素,比如div,假如写成这样就会报错: render(){ return( <div>12 ...

  3. 关于form与表单提交操作的一切

    原文链接:http://caibaojian.com/form.html 你知道,一个表单里面只要有form元素,如果没有给action加一个默认值,为空白的时候,当你刷新页面时,会弹出一个警告框提示 ...

  4. keras Model 3 共享的层

    1 入门 2 多个输入和输出 3 共享层 考虑这样的一个问题:我们要判断连个tweet是否来源于同一个人. 首先我们对两个tweet进行处理,然后将处理的结构拼接在一起,之后跟一个逻辑回归,输出这两条 ...

  5. Linux下设置Tomcat开机自启动

    --未验证 第一步:在/etc/init.d下新建一个文件tomcat(需要root操作权限) vi /etc/init.d/tomcat 然后点击"i"写下如下代码,tomcat ...

  6. https://www.cnblogs.com/

    Linux如何查看端口 1.lsof -i:端口号 用于查看某一端口的占用情况,比如查看8000端口使用情况,lsof -i:8000 # lsof -i:8000 COMMAND PID USER ...

  7. PAT 甲级 1048 Find Coins (25 分)(较简单,开个数组记录一下即可)

    1048 Find Coins (25 分)   Eva loves to collect coins from all over the universe, including some other ...

  8. Python网络编程之TCP套接字简单用法示例

    Python网络编程之TCP套接字简单用法示例 本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而jav ...

  9. LINQ语法详解

    我会通过一些列的实例向大家讲解LINQ的语法. 先创建一个Person类,作为数据实体 public class Person { public string Name { get; set; } p ...

  10. 细说可空类型 nullable PropertyType

    可空类型是System.Nullable结构体的实列.一个可空类型代表了相应值类型的正确范围附加null值.这么说来,其实也不是很明子,命题嘛,一般不求易懂,但求准确. 那我就来说说这可空类型吧,上次 ...