【5002】排版问题
来源:互联网 发布:深圳华夏软件学校招生 编辑:程序博客网 时间:2024/04/30 15:19
Time Limit: 3 second
Memory Limit: 2 MB
【问题描述】
写电子邮件是有趣的,但不幸的是经常写不好看,主要是因为所有的行不一样长,你的上司想要发排版精美的
电子邮件,你的任务是为他编写一个电子邮件排版程序。
完成这个任务最简单的办法是在太短的行中的单词之间插入空格,但这并不是最好的方法,考虑如下例子:
******************(这里的28个*表示要达到的行宽)
This is the example you are
actually considering.
假设我们想将这两行按行宽两端对齐,靠简单地插入空格则我们将得到如下结果:
This is the example you are
actually considering.
但这太难看了,因为在第二行中有一个非常大的空白,如果将第一行的单词“are”移到下一行我们将得到较好的结果:
This is the example you
are actually considering.
当然,这必须对难看程度进行量化。因此我们必须给出单词之间的空格的难看程度,一个包含n个空格符的空白
处,其难看程度值为(n-1)2,程序的目的是使难看程度的总和最小化。例如,第一个例子的难看程度是1+72=50,而
第二个例子的难看程度仅为1+1+1+4+1+4=12。
输出时,每一行的开头和结尾处都必须是一个单词,即每行开头和结尾处不能有空白。唯一例外的是该行仅有一
个单词组成的情况,对于这种情况你可将单词放在该行开头处输出,此时如果该单词比该行应有的长度短则我们指定
它的最坏程度为500,当然在这种情况下,该行的实际长度即为该单词的长度。
【输入】
第一行是一个整数N,表示该段要求达到的行宽度,1<=N<=80。第二行起为文章内容,该段文章由一个或多个单词组成,单词由ASCII码值为33到126(包含33和126)的字符组成,
单词与单词之间用空格隔开(空格的ASCII码是32,可能超过一个)。单词长度不会超过段落要求达到的宽度。一段文字
所有单词的总长度不会超过10000个字符,任何一行都不会超过100个字符,任何一个单词都在同一行内。
文章若从键盘输入,按”F6”键或”Ctrl+Z”键结束,导致eof()为真。
【输出】
对于输入的文章段落,找出使其难看程度最小的排版形式并输出句子:“Minimal badness is B.”,B是指按可能
的最好排版形式会发生的难看程度值。注意排版后文本行数任意,多余的空格或其他控制符号也可删除。
【输入样例】
28
This is the example you are
actually considering.
【输出样例】
Minimal badness is 12.
【题目链接】:http://noi.qz5z.com/viewtask.asp?id=5002
【题解】
可以把中间的那些空格去掉;直接获取所有的单词;存在一个vector里面
设f[i]表示以第i个单词当做一行的最后一个单词的最少难看程度;
分两种转移方式:
1.把第i个单词放在新的一行。题目有说如果这个单词小于需要的长度,则难看程度为500;
2.把第k到第i个单词放在新的一行;
那么问题在于怎么让k到i这些单词放在一行形成的难看程度最小?
必然是让每两个单词之间的空格平均分;即用n减去从k到i这些单词的总长度;设差为rest;则这rest个位置就是要用来加空格的。那么就尽量平方这些空格;
搞个g[i][j]表示从第i到第j个单词放在同一行且这一行只有这些单词时最小难看程度;用递归搞出g(i,j)就好;用递归搞,并不是真的一个数组;
再具体一点
f[0] = 0;for (i=1 -> n){ if (len[i]!=n) f[i] = f[i-1]+500; else f[i] = f[i-1];//难看程度为0 for (k=1 -> i-1) { int temp = f[k-1]+g(k,i); if (temp < f[i]) f[i] = temp; }}
【完整代码】
#include <cstdio>#include <cstring>#include <vector>using namespace std;const int MAXN = 1e4+10;char s[100];int n,f[MAXN],sum[MAXN];vector <int> a;int sqr(int x){ return x*x;}int g(int l,int r){ int tlen = sum[r] - sum[l-1],kg = r-l; if (tlen+kg>n) return 0x3f3f3f3f; tlen = n-tlen; if (!(tlen%kg)) return kg*sqr((tlen/kg)-1); else { int i = tlen/kg,rest = tlen % kg; return kg*sqr(i)-(kg-rest)*(2*i-1);//把每两个单词之间的空格个数当做i+1来做 //然后再减去多余的 //i^2-(i-1)^2 = 2*i-1; }}int main(){ //freopen("F:\\rush.txt","r",stdin); scanf("%d",&n); a.push_back(-1); while (~scanf("%s",s)) { int i = a.size(),len = strlen(s); sum[i] = sum[i-1]+len; a.push_back(len); } int len = a.size()-1; f[0] = 0; for (int i = 1;i <= len;i++) { if (a[i] == n) f[i] = f[i-1]; else f[i] = f[i-1] + 500; for (int k = 1;k <= i-1;k++) { int temp = f[k-1]+g(k,i); if (temp < f[i]) f[i] = temp; } } printf("Minimal badness is %d.\n",f[len]); return 0;}
- 【5002】排版问题
- csdn blog排版问题
- 解决Word排版问题
- csdn排版问题
- javascript排版问题
- word2007目录排版问题
- textview排版问题
- TextView排版问题
- 解决LinearLayout排版问题
- word2010 排版问题
- 排版问题的解决
- dl dt dd排版问题
- 毕业论文的所有排版问题
- word中图片排版问题
- Latex 算法的排版问题
- Thunderbird邮件格式排版问题
- 关于edittext排版问题续
- android textview 排版混乱问题
- 数据结构与算法之大纲
- C++ Builder中制作图片边缘模糊效果的几种方法
- 礼物无货
- alsa-lib和alsa-util在TQ2416上的移植
- Java 包冲突
- 【5002】排版问题
- 屏幕类,用于全屏程序&显示任务栏
- 浮点型 比较
- 抢红包背后的技术点
- liferay中自定义字段及部分路由说明
- k-means算法学习
- Codeforces Round #379 (Div. 2) -- D. Anton and Chess (if else 的水题)
- Python 内置函数 locals()和 globals()
- 双链表的插入学习(C和指针)