UVa 426 Fifth Bank of Swamp County
题目描述题目要求生成已清算支票的汇总列表。输入为按日期排序的支票交易记录每行包含日期、支票号码和金额。输出需按支票号码升序排列并分成三列显示。对于不连续即不是前一个支票号码加111的支票号码需在其后标记星号*。输出格式要求每列之间用三个空格分隔每列包含支票号码可选*、金额和日期。输入格式第一行一个整数NNN表示测试用例的数量后面跟一个空行。接下来NNN组测试用例每组包含若干行每行格式为yy/mm/dd 支票号码 金额金额可能包含前导零、缺少小数部分等不规范格式。每组测试用例之间由一个空行分隔。输入以文件结束符EOF\texttt{EOF}EOF终止。输出格式对于每组测试用例输出三列格式的支票列表按支票号码升序排列。每行的三个条目分别来自三列的同一行位置即先行后列填充。每列格式为nnnn* dddddd.cc yy/mm/dd其中nnnn为支票号码无前导零*为出序列指示符若连续则为空格dddddd.cc为金额至少111位整数部分222位小数小于111美元时整数部分为000yy/mm/dd为日期。列之间用三个空格分隔。每组输出后跟一个空行。样例输入1 93/10/01 998 .65 93/10/01 999 123.89 93/10/05 996 29.99 93/10/06 993 116.52 93/10/12 995 418.00 93/10/15 1001 15045.00 93/10/27 1000 840.85输出993 116.52 93/10/06 998* 0.65 93/10/01 1001 15045.00 93/10/15 995* 418.00 93/10/12 999 123.89 93/10/01 996 29.99 93/10/05 1000 840.85 93/10/27题目分析本题的核心是处理支票数据并按照三列格式输出。需要处理以下几个子任务金额格式化输入金额可能存在各种不规范格式例如缺少整数部分的.65缺少小数部分的123.整数形式无小数点的418带前导零的0.65需要将其规范化为dddddd.cc格式去除前导零但保留至少一位整数若为000则保留一个0。若以小数点开头添加前导0。若以小数点结尾添加两个0。若无小数点添加.00。若小数点后只有一位补一个0。金额大于等于1,000,0001,000,0001,000,000的支票需要忽略题目保证不会出现但仍需处理。出序列标记将支票按号码升序排序后对于每个支票检查其号码是否等于前一个支票号码111。若不是则在该支票号码后标记*否则标记空格。第一张支票的号码不标记*无前一个支票。三列输出输出需要按列填充先填第一列再填第二列最后填第三列。设总支票数为total\textit{total}total行数RRR的计算方式为若total≤3\textit{total} \le 3total≤3则R1R 1R1。否则需要确定RRR使得三列尽可能均匀填充且中间列优先填满。具体计算方式设R⌈total/3⌉R \lceil \textit{total} / 3 \rceilR⌈total/3⌉。第一列左列通常有RRR行但若total mod 31\textit{total} \bmod 3 1totalmod31则第一列需多一行共RRR行但实际分布为第一列RRR行第二列R−1R-1R−1行第三列R−1R-1R−1行需要根据样例推导。观察参考代码的实现它采用了显式分配三列起止索引的方法根据total mod 3\textit{total} \bmod 3totalmod3的值进行分配若total mod 30\textit{total} \bmod 3 0totalmod30每列total/3\textit{total} / 3total/3个元素。若total mod 31\textit{total} \bmod 3 1totalmod31第一列total/31\textit{total} / 3 1total/31第二列total/31\textit{total} / 3 1total/31第三列total/3−1\textit{total} / 3 - 1total/3−1实际代码中计算为total - 4; total / 3;然后第一列total 2第二列2 * total 4第三列末尾。这意味着当total mod 31\textit{total} \bmod 3 1totalmod31时第一列和第二列各多一行。若total mod 32\textit{total} \bmod 3 2totalmod32第一列total/31\textit{total} / 3 1total/31第二列total/31\textit{total} / 3 1total/31第三列total/3\textit{total} / 3total/3。输出格式每行输出三个支票条目若对应列存在。每个条目中支票号码占555列右对齐包括可选的*或空格。金额占101010列右对齐。日期后无额外空格直接输出。列之间用三个空格分隔。复杂度分析每组数据需要排序O(MlogM)O(M \log M)O(MlogM)MMM为支票数量可接受。代码实现// Fifth Bank of Swamp County// UVa ID: 426// Verdict: Accepted// Submission Date: 2016-08-05// UVa Run Time: 0.000s//// 版权所有C2016邱秋。metaphysis # yeah dot net#includebits/stdc.husingnamespacestd;structitem{intnumber;string number_text,money,date;booloperator(constitemanother)const{returnnumberanother.number;}};intmain(intargc,char*argv[]){cin.tie(0);cout.tie(0);ios::sync_with_stdio(false);string line,date,number,money;getline(cin,line);intcasesstoi(line);getline(cin,line);for(inti1;icases;i){if(i1)cout\n;vectoritemchecks;while(getline(cin,line),line.length()0){money0.00;istringstreamiss(line);issdatenumbermoney;// special caseswhile(money.length()0money.front()0)money.erase(money.begin());if(money.length()0)money0.00;if(money.front().)money.insert(money.begin(),0);if(money.back().)money00;if(money.find(.)money.npos)money.00;if(money[money.length()-2].)money.push_back(0);if(money[money.length()-3]!.)money.erase(money.end()-1);if(stod(money)1000000)continue;item data;data.numberstoi(number);data.number_textto_string(data.number);data.moneymoney;data.datedate;checks.push_back(data);}sort(checks.begin(),checks.end());checks[0].number_text ;for(inti1;ichecks.size();i)if(checks[i].number!checks[i-1].number1)checks[i].number_text*;elsechecks[i].number_text ;pairint,intcolumn1,column2,column3;inttotalchecks.size();if(total%30){total/3;column1.first0,column1.secondtotal;column2.firsttotal,column2.second2*total;column3.first2*total,column3.secondchecks.size();}elseif(total%31){total-4;total/3;column1.first0,column1.secondtotal2;column2.firsttotal2,column2.second2*total4;column3.first2*total4,column3.secondchecks.size();}else{total-2;total/3;column1.first0,column1.secondtotal1;column2.firsttotal1,column2.second2*total2;column3.first2*total2,column3.secondchecks.size();}totalchecks.size();for(inticolumn1.first;icolumn1.second;i){coutsetw(5)rightchecks[i].number_text;coutsetw(10)rightchecks[i].money;cout checks[i].date;if(icolumn2.firstcolumn2.secondicolumn2.firsttotal){cout ;coutsetw(5)rightchecks[icolumn2.first].number_text;coutsetw(10)rightchecks[icolumn2.first].money;cout checks[icolumn2.first].date;}if(icolumn3.firstcolumn3.secondicolumn3.firsttotal){cout ;coutsetw(5)rightchecks[icolumn3.first].number_text;coutsetw(10)rightchecks[icolumn3.first].money;cout checks[icolumn3.first].date;}cout\n;}}return0;}