https://hihocoder.com/problemset/problem/1288
题目大概意思就是我们有N个自然段,每个自然段有ai个字符,手机屏幕宽W,长H,让我们字符可设定的最大字体号S,比如字体号为S,则一行只能显示【W/S】向下取整个字符,一个页只能娴熟【H/S】行,最终所有自然段显示的页面不超过P页。
每一个自然段都重新的一行开始显示,自然段之间没有空余的行。
基本思路就是当S定下来的时候,统计所有自然段用了多少行,然后总行数处于一页能显示的行数得到页数,然后与输入P进行比较,没超过P的话就可以尝试加大S。
最简单的思路就是把S从1开始枚举直到使用页超过P页为止,则最后一个满足条件的S就是答案,但是可以看到因为S是单调递增的,可以用二分法来优化搜索过程。
下面是代码
#include<iostream>
#include<math.h>
#include<memory.h>
using namespace std;
int main()
{
int casenum;
cin>>casenum;
while(casenum--)
{
int N,W,H;
long long P;
cin>>N>>P>>W>>H;
int a[N+1];
memset(a,0,sizeof(a));
for(int i=1;i<=N;i++)
{
cin>>a[i];
}
int s=1;
int max_s = min(W,H);
int ans_s=1;
while(s<=max_s)
{
int mid_s = (s+max_s)/2;
int col=floor(1.0*W/mid_s);//该字体大小下的一页能放的列数
int row=floor(1.0*H/mid_s);//该字体大小下的一页能放的行数
int useline=0;
int useP=0;
for(int i=1;i<=N;i++)
{
useline+=ceil(1.0*a[i]/col);//计算自然段用到的总行数;
}
useP = ceil(1.0*useline/row);//计算用到多少页
if(useP > P){
max_s = mid_s-1;//如果使用的页数大于P,则减少一半区间
}else{
//如果小于的话,尝试更大的字体
//先记录这次计算结果是否比历史结果更优
ans_s = max(mid_s,ans_s);
s = mid_s+1;
}
}
cout<<ans_s<<endl;
}
return 0;
}