蓝桥杯—图形排版—暴力破解

1、问题描述

小明需要在一篇文档中加入 N 张图片,其中第 i 张图片的宽度是 Wi,高度是 Hi。
  假设纸张的宽度是 M,小明使用的文档编辑工具会用以下方式对图片进行自动排版:

  1. 该工具会按照图片顺序,在宽度 M 以内,将尽可能多的图片排在一行。该行的高度是行内最高的图片的高度。例如在 M=10 的纸张上依次打印 3x4, 2x2, 3x3 三张图片,则效果如下图所示,这一行高度为4。(分割线以上为列标尺,分割线以下为排版区域;数字组成的矩形为第x张图片占用的版面)

  0123456789
  ----------
  111
  111 333
  11122333
  11122333

  2. 如果当前行剩余宽度大于0,并且小于下一张图片,则下一张图片会按比例缩放到宽度为当前行剩余宽度(高度向上取整),然后放入当前行。例如再放入一张4x9的图片,由于剩余宽度是2,这张图片会被压缩到2x5,再被放入第一行的末尾。此时该行高度为5:

  0123456789
  ----------
  44
  111 44
  111 33344
  1112233344
  1112233344

  3. 如果当前行剩余宽度为0,该工具会从下一行开始继续对剩余的图片进行排版,直到所有图片都处理完毕。此时所有行的总高度和就是这 N 张图片的排版高度。例如再放入11x1, 5x5, 3x4 的图片后,效果如下图所示,总高度为11:

  0123456789
  ----------
  44
  111 44
  111 33344
  1112233344
  1112233344
  5555555555
  66666
  66666777
  66666777
  66666777
  66666777

  现在由于排版高度过高,图片的先后顺序也不能改变,小明只好从 N 张图片中选择一张删除掉以降低总高度。他希望剩余N-1张图片按原顺序的排版高度最低,你能求出最低高度是多少么?

样例输入

4 3
2 2
2 3
2 2

样例输出

2

2、代码实现

import java.util.Scanner;

public class Main{
	//当前排版的宽和高
	static int width;
	static int height;
	//图片个数
	static int pictures;
	//存储图片的尺寸
	static int[][] size;
	//最小的高度
	static int ans = Integer.MAX_VALUE;
	
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		width = scanner.nextInt();
		pictures = scanner.nextInt();
		size = new int[pictures][2];
		for(int i = 0;i < pictures;i++) {
			size[i][0] = scanner.nextInt();
			size[i][1] = scanner.nextInt();
		}
		
		for(int i = 0;i < pictures;i++) {
			//去除第i个图形的高度,找到最小的
			int t = put(i);
			if(t < ans) {
				ans = t;
			}
		}
		System.out.println(ans);
	}
	public static int put(int n) {
		//总的高度
		int h = 0;
		//当前行占用的高度
		int high = 0;
		//当前行占用的宽度
		int w = width;
		for(int i = 0;i < pictures;i++) {
			//不使用第n个图片
			if(i == n) {
				continue;
			}
			// 当前宽度可以放下这张图片
			if(w > size[i][0]) {
				//获取剩余的宽度
				w -= size[i][0];
				//获取占用的高度
				if(size[i][1] > high) {
					high = size[i][1];
				}
			}else {
				//当前宽度不足以放下这张照片,需要调整这张图片的大小
				int adjust = (int) Math.ceil(1.0 * size[i][1] * w / size[i][0]);
				//调整占用的高度
				if(adjust > high) {
					high = adjust;
				}
				//程序执行到此处,说明这张图片是这行的最后一张,该换行了
				h += high;
				high = 0;
				w = width;
			}
		}
		// 当high等于0时表示最后一行是占满的
		// 当high不等于0时表示最后一行未满,且没有加入到总的高度中,所以要加上
		return high == 0 ? h : h + high;
	}


}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@小红花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值