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. Java 学习资料网站集合

    一.开源项目的搜集 https://www.jianshu.com/p/6c75174e0f07 -- https://github.com/flyleft/tip 二.简单的开源项目 https:/ ...

  2. idea 2019激活码

    9MWZD5CC4E-eyJsaWNlbnNlSWQiOiI5TVdaRDVDQzRFIiwibGljZW5zZWVOYW1lIjoiMjAxNzY1MDYxQGNxdS5lZHUuY24gLiIsI ...

  3. XMind 快捷键完整命令

      XMind 快捷键完整命令 快捷键(Windows) 快捷键(Mac) 描述 + + 展开当前分支 - - 收缩当前分支 * * 展开所有分支 / / 收缩所有分支 Alt+- Alt+- 显示系 ...

  4. IIS7下搭建PHP(FastCgiModule)

    windows2008和windows vista都可以安装IIS7 第一步: 下载软件, php官方网站:www.php.net(下载winfows版本) phpmyadmin官方网站:www.ph ...

  5. body-parser 解析post数据

    安装 $ npm install body-parser API var bodyPaeser =require('body-parser') bodyParse.raw(option) 将请求体内容 ...

  6. ubuntu16上启用外部管理端口

    docker启动外部访问端口在Ubuntu上: [root@maintance systemd] $cd /lib/systemd/system/ [root@maintance system] $c ...

  7. keras Model 1 入门篇

    1 入门 2 多个输入和输出 3 共享层 最近在学习keras,它有一些实现好的特征提取的模型:resNet.vgg.而且是带权重的.用来做特诊提取比较方便 首先要知道keras有两种定义模型的方式: ...

  8. SQL-W3School-函数:SQL MID() 函数

    ylbtech-SQL-W3School-函数:SQL MID() 函数 1.返回顶部 1. MID() 函数 MID 函数用于从文本字段中提取字符. SQL MID() 语法 SELECT MID( ...

  9. Python - celery 相关报错 - AttributeError: type object '_multiprocessing.win32' has no attribute 'WAIT_OBJECT_0'

    报错场景 执行   celery worker -A tasks -l INFO  打开 worker 的时候报错无法进行 报错解决 Celery 的版本过高, 进行降级处理即可 pip instal ...

  10. Linux MySql状态、启动、停止、重启命令

    1.查看mysql状态 [1]ps -ef|grep mysqld 看看是否有mysqld_safe 和mysqld进程 [root@localhost ~]# ps -ef|grep mysqld ...