2018 快手笔试题latex爱好者

latex自然是广大研究人员最喜欢使用的科研论文排版工具之一。

月神想在iPhone 上查阅写好的paper,但是无赖iPhone 上没有月神喜欢使用的阅读软件,于是月神也希望像tex老爷爷Donald Knuth那样自己动手do it yourself一个。

在DIY这个阅读软件的过程中,月神碰到一个问题,已知iPhone屏幕的高为H,宽为W,若字体大小为S(假设为方形),则一行可放W / S(取整数部分)个文字,一屏最多可放H / S (取整数部分)行文字。

已知一篇paper有N个段落,每个段落的文字数目由a1, a2, a3,...., an表示,月神希望排版的页数不多于P页(一屏显示一页),那么月神最多可使用多大的字体呢?

1 <= W, H, ai <= 1000

1 <= P <= 1000000

输入描述:

每个测试用例的输入包含两行。

第一行输入N,P,H,W

第二行输入N个数a1,a2,a3,...,an表示每个段落的文字个数。

输出描述:
对于每个测试用例,输出最大允许的字符大小S

示例1

输入

1 10 4 3
10
2 10 4 3
10 10

输出

3
2

 

备注:

以上所有输入、输出均为整数。

且所有测试用例均保证有解。

两个段落之前不空行,并且段落顶格写。

这道题目一看就是典型的二分算法。

这题理解题意有一定难度,这里不用考虑段落前什么的。段落后的空行对应一个向上取整。这里计算的时候先计算所需要的行数,最后再计算所需要的页数。

这里要特别注意向上取整和向下取整的问题,可以使用ceil函数

同时,二分写的时候,最后可以比较left,和right,看看输出left还是输出right

 

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10000;
int arr[N];
int n, P, H, W;
bool check(int mid) {
	int line = 0;
	int page = 0;
	for (int i = 0; i < n; i++) {
		// 先计算行数所需要的行数
		line += ceil(1.0*arr[i] / floor(1.0*(W / mid)));      // 总字数除以每一行的字数向上取整
		// 再计算所需要的页数
	}
	page = ceil(1.0*line / floor(1.0*(H / mid)));        // 总行数除以每一页的行数向上取整
	//cout << line << endl;
	//printf("%d\n", page);
	return page <= P;
}
int main()
{
	
	while (cin >> n >> P >> H >> W) {
		for (int i = 0; i < n; i++) {
			cin >> arr[i];
		}

		int left = 0, right = min(W,H);
		while (left <= right) {
			int mid = left + (right - left) / 2;
			//cout << mid << endl;
			if (check(mid)) {
				left = mid + 1;
			}
			else {
				right = mid - 1;
			}
		}

		printf("%d\n", right);
		
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值