ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

UVa 500 Table

UVa 500 Table

题目描述

题目要求将使用伪图形字符绘制的表格进行自动对齐。表格由横线(-ASCII 196\texttt{ASCII 196}ASCII 196)、竖线(|ASCII 179\texttt{ASCII 179}ASCII 179)和角点字符(如等)组成。表格中的单元格文本可能分布在多行中。对齐后,每个单元格的内容与左右竖线之间应满足:左边恰好一个空格,右边至少一个空格。目标是使表格的总宽度(即每行长度)最小化。

输入格式

第一行一个整数MMM,表示数据集的个数,后面跟一个空行。每个数据集包含一个已编辑的表格,表格行数不超过100100100,每行长度不超过255255255字符。输入行本身不含前导和尾随空格,也不含空行。两个连续数据集之间由一个空行分隔。

输出格式

对于每个数据集,输出对齐后的表格。输出行不应包含前导和尾随空格,也不应有空行。格式化后表格的宽度不超过255255255字符。两个连续数据集的输出之间由一个空行分隔。

样例

输入

1 ┌───────────────┬─────────────┬────────────────────────────────────────┐ │Name │Organization │JOB │ ├───────────────┼─────────────┼────────────────────────────────────────┤ │Bill Clinton │USA │The President of the United States │ │Bill Gates │Microsoft Corporation│President │ │Bill Poucher │A C M │International Collegiate Programming Contest Director│ └───────────────┴─────────────┴────────────────────────────────────────┘

输出

┌──────────────┬──────────────────────┬────────────────────────────────────────────────────────────┐ │Name │Organization │JOB │ ├──────────────┼──────────────────────┼────────────────────────────────────────────────────────────┤ │Bill Clinton │USA │The President of the United States │ │Bill Gates │Microsoft Corporation │President │ │Bill Poucher │A C M │International Collegiate Programming Contest Director │ └──────────────┴──────────────────────┴────────────────────────────────────────────────────────────┘

题目分析

本题的核心是解析由伪图形字符构成的表格,计算每列所需的最小宽度,然后重新绘制表格。

表格结构

表格由以下字符构成:

  • 横线:-ASCII 196\texttt{ASCII 196}ASCII 196
  • 竖线:|ASCII 179\texttt{ASCII 179}ASCII 179
  • 十字交叉点:ASCII 197\texttt{ASCII 197}ASCII 197
  • 角点:218\texttt{218}218)、191\texttt{191}191)、192\texttt{192}192)、217\texttt{217}217
  • 三叉连接:194\texttt{194}194)、193\texttt{193}193)、195\texttt{195}195)、180\texttt{180}180

表格的第一行以开始,最后一行以开始。中间的行以|开始。

列宽计算

表格中每列由竖线分隔,竖线之间的内容为单元格文本。单元格文本可能分布在多行中。对于每列,需要找出该列所有单元格中非空内容的最大宽度(去除前导和尾随空格后的长度)。最终列宽即为该最大宽度。

对齐规则

  • 每个单元格内容与左侧竖线之间恰好有一个空格。
  • 每个单元格内容与右侧竖线之间至少有一个空格(即右侧填充空格数量为列宽 - 内容长度 + 1)。
  • 为最小化表格总宽度,每列宽度取该列所有单元格内容的最大长度。

绘制表格

根据计算出的列宽,重新绘制表格:

  • 绘制顶部边框:+ 若干-++ … +
  • 绘制分隔行:+ 若干-++ … +
  • 绘制底部边框:+ 若干-++ … +
  • 绘制数据行:|+ 空格 + 单元格内容 + 若干空格 +|+ …

算法步骤

  1. 读取整个表格,按行存储。
  2. 扫描表格,识别所有包含竖线的行(即|开头的行),解析每行的单元格内容。
  3. 对于每列,统计所有单元格内容去除前导和尾随空格后的长度,取最大值作为该列宽度。
  4. 根据列宽重新绘制表格:
    • 绘制顶部边框。
    • 绘制数据行(保留原始单元格内容的顺序)。
    • 绘制分隔行(根据原始表格中的分隔行位置决定是否绘制,但题目要求保持原始行数不变?实际上,原始表格的每行(包括横线行)都应保留,但横线行需根据新列宽重新绘制)。
  5. 输出结果。

复杂度分析

表格行数R≤100R \le 100R100,列数C≤256C \le 256C256,每行长度≤255\le 255255,总复杂度O(R×C)O(R \times C)O(R×C)

代码实现

// Table// UVa ID: 500// Verdict: Accepted// Submission Date: 2017-04-17// UVa Run Time: 0.100s//// 版权所有(C)2017,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constcharseparator=(char)(179),right_line_separator=(char)(180),top_right_corner=(char)(191),bottom_left_corner=(char)(192),bottom_line_separator=(char)(193),top_line_separator=(char)(194),left_line_separator=(char)(195),link=(char)(196),middle_line_separator=(char)(197),bottom_right_corner=(char)(217),top_left_corner=(char)(218);voiddrawLine(intcolumns,vector<int>&columnWidth,charleftChar,charmiddleChar,charrightChar){cout<<leftChar;for(inti=0;i<columns;i++){if(i>0)cout<<middleChar;for(intj=0;j<columnWidth[i]+2;j++)cout<<link;}cout<<rightChar<<'\n';}voidprocess(vector<string>&table){vector<int>columnWidth(256,0);intcolumns=0;for(inti=0;i<table.size();i++)if(table[i].front()==separator){istringstreamiss(table[i].substr(1,table[i].length()-1));string block;intc=0;while(getline(iss,block,separator)){intii=0,jj=block.length()-1;while(ii<block.length()&&isblank(block[ii]))ii++;while(jj>=0&&isblank(block[jj]))jj--;if(ii<=jj)columnWidth[c]=max(columnWidth[c],jj-ii+1);c++;}columns=c;}for(inti=0;i<table.size();i++){if(table[i].front()==top_left_corner)drawLine(columns,columnWidth,top_left_corner,top_line_separator,top_right_corner);if(table[i].front()==bottom_left_corner)drawLine(columns,columnWidth,bottom_left_corner,bottom_line_separator,bottom_right_corner);if(table[i].front()==left_line_separator)drawLine(columns,columnWidth,left_line_separator,middle_line_separator,right_line_separator);if(table[i].front()==separator){istringstreamiss(table[i].substr(1,table[i].length()-1));string block;intc=0;while(getline(iss,block,separator)){intii=0,jj=block.length()-1;while(ii<block.length()&&isblank(block[ii]))ii++;while(jj>=0&&isblank(block[jj]))jj--;if(ii<=jj)block=block.substr(ii,jj-ii+1);elseblock.clear();cout<<separator<<' '<<block;cout<<string(columnWidth[c]+1-block.length(),' ');c++;}cout<<separator<<'\n';}}}intmain(intargc,char*argv[]){cin.tie(0);cout.tie(0);ios::sync_with_stdio(false);string line;getline(cin,line);intcases=stoi(line);getline(cin,line);for(intc=1;c<=cases;c++){if(c>1)cout<<'\n';vector<string>table;while(getline(cin,line),line.length()>0)table.push_back(line);process(table);}return0;}
返回列表